1. 主页
  2. 文档
  3. C#进阶
  4. 第二章 泛型
  5. 第四节 协变和逆变

第四节 协变和逆变

static void Main(string[] args)
{
       Console.WriteLine("-------------------------协变和逆变----------------------------");
       People people = new People();
       People people1 = new Teacher(); //因为Teacher是People的子类
       Teacher teacher = new Teacher();

       List<People> pe = new List<People>();
       // List<People> te = new List<Teacher>(); 
       //【1】这样就不行了,从现实中理解应正确才对,两个类型不是一个类型。
       //【2】协变和逆变是针对泛型接口和泛型委托来说的。离开它们就没有这个说法。
       //【3】out关键字代表协变,in代表的是逆变
       //【4】需要用到父类通过子类实例化,或子类通过父类来实例化的情况下就需要用到逆变协变。

       IListOut<People> listOut = new ListOut<People>();
       IListOut<People> listOut1 = new ListOut<Teacher>();  //协变

       IListIn<Teacher> listIn = new ListIn<Teacher>();
       IListIn<Teacher> listIn1 = new ListIn<People>(); //逆变

       IOutInList<Teacher, People> myList1 = new OutInList<Teacher, People>();
       IOutInList<Teacher, People> myList2 = new OutInList<Teacher, Teacher>();//协变
       IOutInList<Teacher, People> myList3 = new OutInList<People, People>(); //逆变
       IOutInList<Teacher, People> myList4 = new OutInList<People, Teacher>();//逆变+协变
}

    /// <summary>
    /// 普通接口
    /// </summary>
    interface IStudy
    {
        //没有构造函数,就是不能实例化
    }
    /// <summary>
    /// 定义一个普通类Study
    /// </summary>
    public class Study
    {
        //默认无参构造函数        
    }
    /// <summary>
    /// 协变只能返回结果,不能做参数。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    interface IListOut<out T>
    {
        T Get();
    }

    class ListOut<T> : IListOut<T>
    {
        public T Get()
        {
           return default(T); //default关键字,如果是值类型默认返回0,是引用默认返回null
        }
    }
    /// <summary>
    /// in修饰,逆变后,T只能作为当参数,不能做返回值。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    interface IListIn<in T>
    {       
        void Show(T t);
    }

    class ListIn<T> : IListIn<T>
    {
        public void Show(T t)
        {
            
        }
    }
    public interface IOutInList<in inT, out outT>
    {
        void Show(inT t);
        outT Get();
        outT Do(inT t);
        //out只能是返回值,in只能是参数,
    }

    public class OutInList<T1, T2> : IOutInList<T1, T2>
    {
        public T2 Do(T1 t)
        {
            return default(T2);
        }

        public T2 Get()  //协变作为返回值
        {
            return default(T2);
        }

        public void Show(T1 t)   //逆变做为参数
        {
            throw new NotImplementedException();
        }
    }
这篇文章对您有用吗?

我们要如何帮助您?