zoukankan      html  css  js  c++  java
  • C# 泛型的协变

        class Program
        {
            static void Main(string[] args)
            {
                Person person = new Person();
                Person chinese2 = new Chinese();//chinese继承自person,所以允许转换
    
    
                List<Person> people = new List<Person>();
                //以下代码不允许。
                //一群中国人难道不是一群人??
                //1、list<people>与list<chinese>没有继承关系。
                //2、若成立,就可以向这个列表中写入people类型数据,也可以写入chinese类型数据,这是类型不安全的
                List<Person> chineses = new List<Chinese>();
    
                //另外一个更容易理解的例子
                //所有类都是Object的子类,若这个转换成立,那么list里可以有各种各样的数据。
                List<object> list = (List<object>)people;
                
                
                //协变
                IMyList<Person> myPeople = new MyList<Chinese>();
                myPeople.Item = new Person();//协变的属性是只读的,所以报错
         
                //协变的前提:
                //1、只有泛型接口和泛型委托才可以协变,详见MyList2类
                //2、协变的类型实参只能是引用类型,不能是值类型
                IMyList<object> myList1 = new MyList<int>();
    
            }
        }
    
        class Person
        {
            public int ID { get; set; }
            public string Name { get; set; }
        }
    
        class Chinese: Person
        {
            public string Gender { get; set; }
        }
        /// <summary>
        /// c#4.0起,使用out 类型参数修饰符允许协变。
        /// 协变类型参数只能是只读;
        /// out修饰符会让编译器验证T是否真的只用作“输出”,且永远不用于形参或属性的赋值方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        interface IMyList< out T>
        {
           
            public T Item { get;}
            /// <summary>
            /// out 修饰的类型参数必须是只读,所以代码报错
            /// </summary>
            public T Item2 { get; set; }
            /// <summary>
            /// out 修饰的类型参数不能做为形参,所以代码报错
            /// </summary>
            /// <param name="t"></param>
            public void SetValue(T t);
          
    
        }
        /// <summary>
        /// 实现接口类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        class MyList<T> : IMyList<T>
        {
            public T Item => default(T);
    
           public T Item2 { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    
            public void SetValue(T t)
            {
              
            }
        }
        /// <summary>
        /// 只有泛型接口和泛型委托才可以协变。泛型类型与结构永远不可协变
        /// </summary>
        /// <typeparam name="T"></typeparam>
        class MyList2<out T>
        { }
  • 相关阅读:
    数组中的趣味题二
    数组中的趣味题一
    归并排序
    堆内存与栈内存
    c++中的继承和组合
    直接插入排序
    NYOJ 1067 Compress String(区间dp)
    C++ Primer 学习笔记与思考_7 void和void*指针的使用方法
    ucgui界面设计演示样例2
    手机无法连接电脑的手机助手
  • 原文地址:https://www.cnblogs.com/ilyyin/p/13566321.html
Copyright © 2011-2022 走看看