泛型委托和泛型接口的逆变协变类型参数

.NET4.0为泛型接口和委托引入了新内容,逆变和协变类型参数。利用这个功能可将泛型委托和接口的一个变量转型为同一个泛型类型的另一个变量(后者的泛型类型实参不同)。

逆变量:说明泛型类型参数可以从一个基类更改为该类的派生类。在C#中用in关键字标记。用作方法的参数。

协变量:说明泛型类型参数可以从一个派生类更改为它的基类。在C#中用out关键字标记。用作方法的返回值。

下面用代码说明它的用法:(代码只用作说明用法)

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




你可能感兴趣的:(泛型委托和泛型接口的逆变协变类型参数)