c# の第 3 版による CLR には、私には理解できない例があります。
不変 そのジェネリック型パラメーターを変更できないことを意味します。この章ではこれまで、不変のジェネリック型パラメーターのみを示してきました。n
反変 ジェネリック型パラメーターがクラスから派生したクラスに変更できることを意味します。C# では、反変のジェネリック型パラメーターをin キーワードで示します。
反変のジェネリック型パラメーターは、メソッドの引数などの入力位置にのみ表示できます。n 共変 ジェネリック型引数がクラスからその基底クラスの 1 つに変更できることを意味します。C# では、共変のジェネリック型パラメーターをout キーワードで示します。共変のジェネリック型パラメーターは、メソッドの戻り値の型などの出力位置にのみ表示できます。
次に、著者は次の例を挙げます。
public delegate TResult Func<in T, out TResult>(T arg);
ここで、ジェネリック型パラメーター T は in キーワードでマークされ、反変になります。ジェネリック型パラメーター TResult は out キーワードでマークされ、共変になります
ここで、次のページ (292) で問題に遭遇します。彼は、インターフェイスを使用するときに反対のことを言います。
一般的な引数を取り、値を返すデリゲートを使用する場合は、できる限り反変性と共変性の in キーワードと out キーワードを常に指定することをお勧めします。これにより、悪影響がなく、より多くのシナリオでデリゲートを使用できるようになります。デリゲートと同様に、ジェネリック型パラメーターを持つインターフェイスは、その型パラメーターを反変または共変にすることができます。以下は、反変 >generic 型パラメーターを使用したインターフェイスの例です。
public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}
T は反変であるため、次のコードを正常にコンパイルして実行することができます。
// This method accepts an IEnumerable of any reference type
Int32 Count(IEnumerable<Object> collection) { ... }
...
// The call below passes an IEnumerable<String> to Count
Int32 c = Count(new[] { "Grant" });
2 番目の例では、out キーワード ( IEnumerator<out T>
) を使用し、それを反変と呼んでいます。これは正しいですか、何か不足していますか。インターフェイスで反変と共変を定義する違いはありますか? 私はこの本に関して Oreilly の Web サイトにアクセスしましたが、これはリストされていません。