Covariance, Contravariance 觀念分享
                             Howard
Covariance

string[] strings = new string[3];
object[] objects = strings;

// RunTimeError !! 發生 ArrayTypeMismatchException!
objects[0] = DateTime.Now;
string s = (string)objects[0];
Covariance – generic types


List<string> stringList = new List<string>();
List<object> objectList = stringList;

Cannot implicitly convert type 'System.Collections.Generic.List<string>' to
'System.Collections.Generic.List<object>’


泛型本身具有不變性( invariance )
Covariance in .Net 4.0
List<string> stringList = new List<string>();

// C# 2/3 不允許, C# 4.0 OK!
IEnumerable<object> objects = stringList;



WHY ?
Covariance in .Net 4.0
public interface IEnumerable<out T> : Ienumerable
{

     IEnumerator<T> GetEnumerator();
}

型別 T 在這個泛型介面中只能用於 method 的傳回值,而不能用來當
作 method 的參數

public interface IFoo<out T>
{
          // 編譯失敗:型別 T 在這裡只能用於方法的傳回值,不可當
作參數。
          string Convert(T obj);
          T GetInstance();    // OK!
}
Covariance in .Net 4.0
 用 IEnumerable<T> 把一串物件包起來,難道不會跟前面
 的陣列 covariance 範例一樣產生型別安全的問題嗎?

 答案是不會。因為 IEnumerable<T> 的操作都是唯讀的,你無法透
 過它去替換或增刪串列中的元素。
Contravariance
   跟 Covariance 相反 - in

static object GetObject() { return null; }
     static void SetObject(object obj) { }
     static string GetString() { return ""; }
     static void SetString(string str) { }


static void Test()
     {
       // Covariance. A delegate specifies a return type as object,
       // but you can assign a method that returns a string.
       Func<object> del = GetString;

  // Contravariance. A delegate specifies a parameter type as string,
       // but you can assign a method that takes an object.

  Action<string> del2 = SetObject;
    }
Contravariance

public interface MyIComparer<in Tin>
{

       int Compare(Tin left, Tin right);
}
結論
 In .NET Framework 4, both C# and Visual Basic support
  covariance and contravariance in generic interfaces and
  delegates and allow for implicit conversion of generic type
  parameters.
Reference
 C# 4.0 : Covariance 與 Contravariance 觀念入門
   http://huan-lin.blogspot.com/2009/10/c-40covariance-and-
     contravariance.html

 Covariance and Contravariance (C# and Visual Basic)
   http://msdn.microsoft.com/en-us/library/ee207183.aspx
Q&A

Covariance, contravariance 觀念分享

  • 1.
  • 2.
    Covariance string[] strings =new string[3]; object[] objects = strings; // RunTimeError !! 發生 ArrayTypeMismatchException! objects[0] = DateTime.Now; string s = (string)objects[0];
  • 3.
    Covariance – generictypes List<string> stringList = new List<string>(); List<object> objectList = stringList; Cannot implicitly convert type 'System.Collections.Generic.List<string>' to 'System.Collections.Generic.List<object>’ 泛型本身具有不變性( invariance )
  • 4.
    Covariance in .Net4.0 List<string> stringList = new List<string>(); // C# 2/3 不允許, C# 4.0 OK! IEnumerable<object> objects = stringList; WHY ?
  • 5.
    Covariance in .Net4.0 public interface IEnumerable<out T> : Ienumerable { IEnumerator<T> GetEnumerator(); } 型別 T 在這個泛型介面中只能用於 method 的傳回值,而不能用來當 作 method 的參數 public interface IFoo<out T> { // 編譯失敗:型別 T 在這裡只能用於方法的傳回值,不可當 作參數。 string Convert(T obj); T GetInstance(); // OK! }
  • 6.
    Covariance in .Net4.0  用 IEnumerable<T> 把一串物件包起來,難道不會跟前面 的陣列 covariance 範例一樣產生型別安全的問題嗎? 答案是不會。因為 IEnumerable<T> 的操作都是唯讀的,你無法透 過它去替換或增刪串列中的元素。
  • 7.
    Contravariance  跟 Covariance 相反 - in static object GetObject() { return null; } static void SetObject(object obj) { } static string GetString() { return ""; } static void SetString(string str) { } static void Test() { // Covariance. A delegate specifies a return type as object, // but you can assign a method that returns a string. Func<object> del = GetString; // Contravariance. A delegate specifies a parameter type as string, // but you can assign a method that takes an object. Action<string> del2 = SetObject; }
  • 8.
    Contravariance public interface MyIComparer<inTin> { int Compare(Tin left, Tin right); }
  • 9.
    結論  In .NETFramework 4, both C# and Visual Basic support covariance and contravariance in generic interfaces and delegates and allow for implicit conversion of generic type parameters.
  • 10.
    Reference  C# 4.0: Covariance 與 Contravariance 觀念入門  http://huan-lin.blogspot.com/2009/10/c-40covariance-and- contravariance.html  Covariance and Contravariance (C# and Visual Basic)  http://msdn.microsoft.com/en-us/library/ee207183.aspx
  • 11.