.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(); } }