CSharp

ジェネリックの共変性と反変性

http://msdn.microsoft.com/ja-jp/library/vstudio/dd799517.aspx

共変性

Base という基本クラスと、Derived という派生クラスがあるとします。ポリモーフィズムによって、Derived のインスタンスを Base 型の変数に代入できます。

IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;

反変性

Action<Base> b = (target) => { Console.WriteLine(target.GetType().Name); };
Action<Derived> d = b;
d(new Derived());

共変性と反変性は、"分散" と総称されます。 共変または反変としてマークされていないジェネリック型パラメーターは、不変と呼ばれます。 共通言語ランタイムにおける分散について、簡潔な概要を示します。

1、.NET Framework 4 のバリアント(Variant)型パラメーターは、ジェネリック インターフェイス型と汎用デリゲート型に制限されています。
2、ジェネリック インターフェイス型や汎用デリゲート型では、共変と反変の両方の型パラメーターを使用できます。
3、分散が適用されるのは参照型のみです。バリアント型パラメーターに対して値型を指定すると、その型パラメーターが、結果の構築型で不変になります。
4、分散は、デリゲートの組み合わせには適用されません。 つまり、Action<Derived> 型と Action<Base> 型の 2 つのデリゲートがある場合、結果はタイプ セーフになりますが、2 つ目のデリゲートに 1 つ目のデリゲートを組み合わせることはできません。 分散によって 2 つ目のデリゲートを Action<Derived> 型の変数に代入できますが、デリゲートを組み合わせることができるのは、それらの型が完全に一致している場合だけです。

共変の型パラメーターを持つジェネリック インターフェイス

  • IEnumerable<T>
  • IEnumerator<T>
  • IQueryable<T>
  • IGrouping<TKey, TElement>

反変の型パラメーターを持つジェネリック インターフェイス

  • IComparer<T>
  • IComparable<T>
  • IEqualityComparer<T>
public class Base { }
public class Derived : Base { }

class Program
{
    public static Derived MyMethod(Base b)
    {
        return b as Derived ?? new Derived();
    }

    static void Main(string[] args)
    {
        Func<Base, Derived> f1 = MyMethod;

        // 共変リターンタイプ
        Func<Base, Base> f2 = f1;
        Base b2 = f2(new Base());

        // 反変パラメータタイプ
        Func<Derived, Derived> f3 = f1;
        Derived d3 = f3(new Derived());

        // 共変リターンタイプAND反変パラメータタイプ
        Func<Derived, Base> f4 = f1;
        Base b4 = f4(new Derived());
    }
}


★月額105円~/容量最大30GB/機能満載! ロリポップ!レンタルサーバー ★

コメント:



(画像の文字列を入力して下さい)

トップ   編集 凍結 差分 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019/12/02 (月) 12:33:18 (1627d)

PCpዾyǗlgĂ܂}WŔ܂z 萔O~ył񂫁z Yahoo yV NTT-X Store

z[y[W ̃NWbgJ[h COiq ӂ邳Ɣ[ COsیI COze