共変性(covariance)と反変性(contravariance)は、ある型が別の型に変換可能な性質をもっている、ということを意味する。可能なときはいつでも、ジェネリックなインターフェイスを装飾して、ジェネリックの共変性と反変性をサポートできるようにすべきである。
- 共変性: 継承関係において、より上方の型に変換可能である
- 反変性: 継承関係において、より下方の型に型に変換可能である
C# 4.0より前では、全てのジェネリック型は不変(invariant)だった。C# 4.0以降では、新しいキーワードを使うことで、共変性と反変性をサポートすることができる。
パラメータにout
修飾子をつけると、 (1) メソッドの戻り値 (2) プロパティのgetアクセサ にしか使えなくなる。out
修飾子による制限のため、T
の内容は変更されることがないため、より上方の型への変換は安全に行うことができる。
以下は、out
修飾子を使用しているIEnumerator<T>
の例である。
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
new T Current { get; }
}
以下のように、Enumerator<T>
には共変性がある(ベース型に変換できる)。
Enumerator<string> strEnum = new Enumerator<string>();
Enumerator<object> objEnum = strEnum;
逆に、in
修飾子を使うことで、メソッドのパラメータにしか使えないように制限することができる。
public interface IComparer<in T>
{
int Compare(T a, T b);
}
以下のように、Comparer<T>
には反変性がある(派生型に変換できる)。
IComparer<object> objComp = new Comparer<object>();
IComparer<string> strComp = objComp;