1

私が直面しているシナリオは次のとおりです。

public abstract class Record { } 

public abstract class TableRecord : Record { } 

public abstract class LookupTableRecord : TableRecord { } 

public sealed class UserRecord : LookupTableRecord { } 

public interface IDataAccessLayer<TRecord> 
    where TRecord : Record { } 

public interface ITableDataAccessLayer<TTableRecord> : IDataAccessLayer<TTableRecord> 
    where TTableRecord : TableRecord { } 

public interface ILookupTableDataAccessLayer<TLookupTableRecord> : ITableDataAccessLayer<TLookupTableRecord> 
    where TLookupTableRecord : LookupTableRecord { } 

public abstract class DataAccessLayer<TRecord> : IDataAccessLayer<TRecord> 
    where TRecord : Record, new() { } 

public abstract class TableDataAccessLayer<TTableRecord> : DataAccessLayer<TTableRecord>, ITableDataAccessLayer<TTableRecord> 
    where TTableRecord : TableRecord, new() { } 

public abstract class LookupTableDataAccessLayer<TLookupTableRecord> : TableDataAccessLayer<TLookupTableRecord>, ILookupTableDataAccessLayer<TLookupTableRecord> 
    where TLookupTableRecord : LookupTableRecord, new() { } 

public sealed class UserDataAccessLayer : LookupTableDataAccessLayer<UserRecord> { }

UserDataAccessLayer を一般的な基本型にキャストしようとするとITableDataAccessLayer<TableRecord>、コンパイラは型を暗黙的に変換できないと不平を言います。

inジェネリック パラメーターのインターフェイス宣言でorキーワードを使用しようとすると、コンパイラは無効な差異outについて不平を言います: 型パラメーターは不変的に有効である必要があります。

次の抽象クラスがあります。

public abstract class FileProcessor : IDisposable
{
    protected abstract ITableDataAccessLayer<TableRecord> CreateTableDataAccessLayer();
}

具体的な実装例は次のとおりです。

public class UserFileProcessor : FileProcessor
{
            protected override ITableDataAccessLayer<TableRecord> CreateTableDataAccessLayer()
        {
            return new UserDataAccessLayer();
        }
}

新しい UserDataAccessLayer() を返します。コンパイラが不平を言っているところです。

4

2 に答える 2

0

共分散と反分散の問題は、関連する型にかなりの制限が課されることであり、すべての場合に適用できるとは限りません。

次の変更を加えることで、コードをコンパイルすることができました。

public interface IDataAccessLayer<out TRecord>
    where TRecord : Record { }

public interface ITableDataAccessLayer<out TTableRecord> : IDataAccessLayer<TTableRecord>
    where TTableRecord : TableRecord { }

ノート:

  • IDataAccessLayer および ITableDataAccessLayer に out が追加されました

ただし、これは、これらの型の出力位置でのみ TTableRecord を使用することに制限されないことを意味します。つまり、次のことを意味します。

  • 読み取り専用プロパティの型 (書き込み可能なプロパティではない)
  • メソッドの戻り値の型
  • メソッドの out 引数の型

次の用途には使用できません。

  • 書き込み可能なプロパティ
  • メソッドへの ref または非 out/ref パラメーター

おそらく、共分散と反分散をここで役立てる方法はありません。

于 2010-04-30T10:11:43.267 に答える
0

私の知る限り、共分散を使用する場合は、インターフェイスに out キーワードを指定する必要があります。

http://geekswithblogs.net/NewThingsILearned/archive/2009/09/30/covariance-in-.net-4.0.aspx

于 2010-04-30T09:06:18.460 に答える