.NET4.0爲泛型接口和委託引入了新內容,逆變和協變類型參數。利用這個功能可將泛型委託和接口的一個變量轉型爲同一個泛型類型的另外一個變量(後者的泛型類型實參不一樣)。c#
逆變量:說明泛型類型參數能夠從一個基類更改成該類的派生類。在C#中用in關鍵字標記。用做方法的參數。spa
協變量:說明泛型類型參數能夠從一個派生類更改成它的基類。在C#中用out關鍵字標記。用做方法的返回值。code
下面用代碼說明它的用法:(代碼只用做說明用法)繼承
interface Icomparable<in T,out Tout>//T爲逆變量 Tout爲協變量 { Int32 CompareTo(T i);//逆變類型實參用做方法的參數 Tout Exception();//協變類型實參用做返回值類型 } class point : Icomparable<object,NullReferenceException>繼承逆變類型實參爲object協變類型實參爲NullReferenceException的泛型接口 { private Int32 m_x; private Int32 m_y; public point(Int32 x, Int32 y) { m_x = x; m_y = y; } ///實現接口方法 public Int32 CompareTo(object i) { return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y) - Math.Sqrt(((point)i).m_x * ((point)i).m_x + ((point)i).m_y * ((point)i).m_y)); } ///實現接口方法 public NullReferenceException Exception() { NullReferenceException e=null; return e; } } class Program { static void Main(string[] args) { Icomparable<object,NullReferenceException> a = new point(1,2);接口變量應用類型point的一個實例 Icomparable<String,Exception> b = a;//因爲使用了協變類型實參和逆變類型實參,因此這條語句執行成功。 //若是類型參數沒有用in 標識爲逆變量則上面語句報錯。 錯誤 1 沒法將類型「接口.Icomparable<object,System.NullReferenceException>」隱式轉換爲「接口.Icomparable<string,System.Exception>」。存在一個顯式轉換(是否缺乏強制轉換?) C:\Users\Administrator\documents\visual studio 2013\Projects\接口\接口\Program.cs 45 47 接口 //若是類型參數沒有用out標識爲協變量則上面語句一樣報錯。 錯誤 1 沒法將類型「接口.Icomparable<object,System.NullReferenceException>」隱式轉換爲「接口.Icomparable<string,System.Exception>」。存在一個顯式轉換(是否缺乏強制轉換?) C:\Users\Administrator\documents\visual studio 2013\Projects\接口\接口\Program.cs 45 47 接口 Console.Read(); } }