msdn のドキュメント ( http://msdn.microsoft.com/en-us/library/tfakywbh.aspx ) では、キーワード「in」のような比較デリゲートの構文が報告されています。
public delegate int Comparison<in T>(
T x,
T y
)
「で」には実際の意味がありますか?そこに表示される可能性のある他のキーワードはありますか?
msdn のドキュメント ( http://msdn.microsoft.com/en-us/library/tfakywbh.aspx ) では、キーワード「in」のような比較デリゲートの構文が報告されています。
public delegate int Comparison<in T>(
T x,
T y
)
「で」には実際の意味がありますか?そこに表示される可能性のある他のキーワードはありますか?
in
ジェネリック パラメーターが反変であることを意味します。これは、この場合、 を に割り当てることができることを意味しComparison<Base>
ますComparison<Derived>
。
変数は型パラメーターComparison<Derived>
を取るメソッドを受け入れることができるため、これを行うことができます。Base
を呼び出すときはComparison<Derived>
、変数を渡す必要がありDerived
ます。これはたまたま有効なパラメーターであり、パラメーターを受け入れるメソッドに渡されBase
ます。これは、 を に代入することが理にかなっていることを意味しComparison<Base>
ますComparison<Derived>
。
の反対in
は (自然に)out
です。これは、パラメーターが共変であり、Derived
ジェネリックをジェネリックに割り当てることができることを意味しますBase
。これは、デリゲートの戻り値の型を指定する場合などに使用されます。
どれがどれであるかを覚えておく便利な方法:
in
渡されるだけの型にのみout
使用する必要があります。 渡されるだけの型にのみ使用する必要があります。
ここでもっと読む:
このデリゲートは反変であり、in
キーワードはT
入力型としてのみ使用されることを意味します。反変性とは、このデリゲート型が定義されていることを意味します。
public delegate int Comparison<in T>(T x, T y);
あなたはこれを行うことができます:
Comparison<Control> comp1 = (a, b) => (a.Width*a.Height - b.Width*b.Height);
Comparison<TextBox> comp2 = comp1;
キーワードがないin
と、あるタイプを別のタイプに変換できないという 2 行目のエラーが表示されます。しかし、これは入力のみに使用されることがわかっているため、 (input) を提供することが期待されるデリゲート ポインターにT
処理するデリゲートを割り当てることは合法です。結局、に収まります。Control
TextBox
TextBox
Control
一方、共分散があります。また、他の型に適合する型にも依存しますが、今回は結果 (この場合はデリゲートの結果) 用です。
総称して分散として知られる共分散と反分散は、ジェネリック デリゲートだけでなく、ジェネリック クラスとインターフェイスにも適用されます。Variance は非ジェネリックなデリゲートと配列でも機能しますが、暗黙的な方法で行われるため、特別なキーワードは必要ありません。ただ機能します。
分散は簡単なテーマではなく、私の説明を Eric Lippert の一連のブログ記事と比較することはできません。これは 2007 年のもので、彼は未来形で .NET4 C# について語っていますが、それでも非常に読み応えがあります。
型パラメーターに "in" 宣言を適用することは、基本型オブジェクトを受け入れるデリゲートが与えられた場合に、派生型オブジェクトを受け取るデリゲートを期待するルーチンをコンパイラが許可することを意味します。たとえば、デリゲートがシマウマを処理することを期待するルーチンは、コンパイル時の観点から、すべての動物を処理できるデリゲートが与えられた場合に完全に満足します。
ただし、注意すべき重要なことは、MulticastDelegate
とが実装されている残念な方法のため、実行時にクラッシュを引き起こす可能性のあるDelegate.Combine
コードで共変デリゲートを使用しようとすると、まったく同じ型の 2 つのデリゲートが必要になるためです。 . 異なる型のデリゲートを結合するジェネリック メソッドがあればいいのですが (メソッド自体には、両方のデリゲートが満足できる型を指定する必要があります)。そのクラスは、1 つのデリゲート型の型情報のみを保持します)。しかし、今のところそのような方法はありません。Delegate.Combine
Delegate.Combine
MulticastDelegate