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>
        { }
  • 相关阅读:
    线性可分支持向量机
    谈对牛顿法的理解
    最大熵模型学习笔记
    Maven --- <distributionManagement>标签
    poi-word导出,导出多图片到word
    poi-excel导入导出
    ApplicationContextInitializer接口
    springboot伪静态
    springboot集成邮件服务
    多文件上传demo
  • 原文地址:https://www.cnblogs.com/ilyyin/p/13566321.html
Copyright © 2011-2022 走看看