• 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>
        { }
  • 相关阅读:
    IOS中NSUserDefaults的用法(轻量级本地数据存储)
    ios:Failed to instantiate the default view controller for UIMainStoryboardFile 'Main'
    NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)"
    使用AFNetworking 报错提示
    对比iOS网络组件:AFNetworking VS ASIHTTPRequest(转载)
    iOS
    如何理解语言的跨平台性
    R语言演示功能
    R 字符串处理函数
    来自 Google 的 R 语言编码风格指南
  • 原文地址:https://www.cnblogs.com/ilyyin/p/13566321.html
Copyright © 2020-2023  润新知