ジェネリック(ジェネリクス) 制約がまた増えた

基本文法

ジェネリック(ジェネリクス)

ジェネリック(ジェネリクス)とは、型パラメータを指定することにより、その型に応じたクラスやメソッドなどを実現する機能のこと。

<T>のように<>で指定する。

ジェネリッククラスとジェネリックメソッド

class GenericClassSample<T>
{
    public void GenericMethodSample<T>(T t)
    {
    }
}

ジェネリック型制約

whereを指定することにより型に制約を付与する
C# 7.3 以降はEnum、Delegate、MulticastDelegateも指定可能に
C# 8.0 以降で null非許容も指定可能に
    // インタフェース
    public class AGenericClass<T> where T : IComparable<T> { }

    // 列挙体
    public class UsingEnum<T> where T : System.Enum { }

    // デリゲート
    public class UsingDelegate<T> where T : System.Delegate { }

    // マルチキャストデリゲート
    public class Multicaster<T> where T : System.MulticastDelegate { }

    // クラス(参照型)と構造体(値型)
    public class MyClass<T, U> where T : class where U : struct { }

    // 非NULL許容型
#nullable enable
    public class NotNullContainer<T> where T : notnull { }
#nullable restore

    // アンマネージド
    public class UnManagedWrapper<T> where T : unmanaged { }

    // デフォルトコンストラクタが定義されていること
    public class GenericClass<T> where T : new()
    {
        T item = new T();
    }

既定値

指定されたタイプにより、値型ならその規定値(数値型の場合は0)を、参照型ならNullを返す
class GenericSample
{
    static T GetDefaultValue<T>()
    {
        // default(type)の戻値が既定値
           return default(T);
    }

    static void Main(string[] args)
    {
        var ret1 = GetDefaultValue<int>();             // 0
        var ret3 = GetDefaultValue<GenericSample>();   // Null
    }
}

共変性(Covariance)と反変性(Contravariance)とInvariance(訳語不明:不変性?)

暗黙の変換に関する規則。ソース内コメント参照のこと

共変性(Covariance)とは派生クラスのインスタンスを規定クラスに割りてるようなこと
反変性(Contravariance)とは逆で規定クラス側のインスタンスを派生型に割り当てるようなこと
不変性(Invariance)とはそのどちらもできないこと(値型は継承できないのでこれ)
static void Main(string[] args)
{
    // string型はobject型を継承しているので代入可能
    string str = "test";
    object obj = str;
 
    // ジェネリックではこの代入ができない。下記コードはコンパイルエラーとなる。
    // ここで、IList型は IList<T> と定義されている。
     
    //IList<string> strList = new List<string>();
    //IList<object> objList = strList;
 
    // Covariance 共変性(代入互換性)
    // <out T>のように定義されている場合、この代入が可能となる。
    // IEnumerable<out T> : IEnumerable
    IEnumerable<string> strEnumerable = new List<string>();
    IEnumerable<object> objEnumerable = strEnumerable;
 
    // 反変性
    // 共変性の逆。<in T>と定義があれば可能
    //  Action<in T>
    Action<object> objAction = _obj => Console.WriteLine(_obj);
    Action<string> strAction = objAction;
     
}