<out T>
と<T>
の違いは何ですか?例えば:
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
ジェネリックのout
キーワードは、インターフェイスのタイプTが共変であることを示すために使用されます。詳細については、 共分散と反分散 を参照してください。
古典的な例はIEnumerable<out T>
です。 IEnumerable<out T>
は共変なので、次のことを行うことができます。
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
文字列はオブジェクトから派生するため、論理的には機能するはずですが、これが共変ではない場合、上記の2行目は失敗します。 汎用インターフェイスの違い がC#およびVB.NET(VS 2010を備えた.NET 4)に追加される前は、これはコンパイル時エラーでした。
.NET 4の後、IEnumerable<T>
は共変とマークされ、IEnumerable<out T>
になりました。 IEnumerable<out T>
はその中の要素のみを使用し、それらを追加/変更することはないため、列挙可能な文字列のコレクションをオブジェクトの列挙可能なコレクションとして扱うのは安全です。つまり、covariant。
IList<T>
にはAdd
メソッドがあるため、これはIList<T>
のような型では機能しません。これが許可されると仮定します:
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
次に電話することができます:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
もちろん、これは失敗します-したがって、IList<T>
は共変としてマークできません。
ところで、in
のオプションもあります-これは比較インターフェースのようなものによって使用されます。たとえば、IComparer<in T>
は逆の動作をします。 IComparer<Foo>
インターフェイスはであるため、Bar
がFoo
のサブクラスである場合、具体的なIComparer<Bar>
をIComparer<in T>
として直接使用できます。反変。
in
およびout
キーワードの使用(共分散と反分散も)を簡単に思い出すために、継承をラッピングとしてイメージできます。
String : Object
Bar : Foo
考えて、
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
および機能、
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
ICovariantSkinned<Fruit>
は共変インターフェイスであり、Banana
はFruit
のタイプであるため、ICovariantSkinned<Fruit>
を受け入れる関数はICovariantSkinned<Bananna>
またはICovariantSkinned<T>
を受け入れることができます。 、
ISkinned<Fruit>
を受け入れる関数は、ISkinned<Fruit>
のみを受け入れることができます。
「out T
」は、タイプT
が「共変」であることを意味します。これにより、T
がジェネリッククラス、インターフェイス、またはメソッドのメソッドで返される(アウトバウンド)値としてのみ表示されるように制限されます。これは、タイプ/インターフェース/メソッドを、T
のスーパータイプを持つ同等のものにキャストできることを意味します。
例えば。 ICovariant<out Dog>
はICovariant<Animal>
にキャストできます。
投稿したリンクから...
ジェネリック型パラメーターの場合、outキーワードは、型パラメーターが共変であることを指定します。
編集:もう一度、投稿したリンクから
詳細については、「共分散と反分散(C#およびVisual Basic)」を参照してください。 http://msdn.Microsoft.com/en-us/library/ee207183.aspx