美文网首页csharp
Unity 基础之 Where约束与协变、逆变

Unity 基础之 Where约束与协变、逆变

作者: su9257_海澜 | 来源:发表于2018-05-15 11:54 被阅读43次
    约束 描述
    where T: struct 类型参数必须为值类型
    where T : class 类型参数必须为引用类型
    where T : new() 类型参数必须有一个公有、无参的构造函数。当于其它约束联合使用时,new()约束必须放在最后。
    where T : <base class name> 类型参数必须是指定的基类型或是派生自指定的基类型
    where T : <interface name> 类型参数必须是指定的接口或是指定接口的实现。可以指定多个接口约束。接口约束也可以是泛型的

    示例

    Play函数传入的参数必须满足
    • 参数为引用类型
    • 必须是CustomClass01的子类或者派生类
    • 必须含有无参构造函数
    • 必须继承Iplay接口
    public class CustomClass01
    {
        public int id;
    }
    public interface IPlay
    {
        void PlayGame();
    }
    
    public class CustomGeneric
    {
    
        public void Play<T>(T parameter) where T : CustomClass01, IPlay,new()
        {
            int Tempi = parameter.id;
            parameter.PlayGame();
            parameter = null;
        }
    }
    

    协变&&逆变

    在具有继承关系的两个类 Father(基类)和Son(派生类)中,会出现如下编译错误


    常规泛型解决办法
                    List<Father> FatherList3 = new List<Son>().Select(c => (Father)c).ToList();
    

    但是使用协变和逆变可解决上面的问题

    协变与逆变也有他们对应的约束

    • 协变 out 只能是返回结果 修饰返回值
    • 逆变 in 只能是参数 修饰传入参数
    • 协变逆变 只能放在接口或者委托的泛型参数前面
    相应全部代码
        /// <summary>
        /// .net4.0
        /// 只能放在接口或者委托的泛型参数前面
        /// out 协变covariant    修饰返回值 
        /// in  逆变contravariant  修饰传入参数
        /// </summary>
        public class Test
        {
            public static void Show()
            {
                {
                    Father bird1 = new Father();
                    Father bird2 = new Son();
                    Son Son1 = new Son();
                    //Son Son2 = new Father();
                }
    
                {
                    List<Father> birdList1 = new List<Father>();
                    //List<Father> FatherList2 = new List<Son>();
    
    
                    List<Father> FatherList3 = new List<Son>().Select(c => (Father)c).ToList();
                }
                {
                    //协变
                    IEnumerable<Father> FatherList1 = new List<Father>();
                    IEnumerable<Father> FatherList2 = new List<Son>();
    
                    Func<Father> func = new Func<Son>(() => null);
    
                    ICustomerListOut<Father> customerList1 = new CustomerListOut<Father>();
                    ICustomerListOut<Father> customerList2 = new CustomerListOut<Son>();
                }
                {//逆变
                    ICustomerListIn<Son> customerList2 = new CustomerListIn<Son>();
                    ICustomerListIn<Son> customerList1 = new CustomerListIn<Father>();
    
                    ICustomerListIn<Father> FatherList1 = new CustomerListIn<Father>();
                    FatherList1.Show(new Son());
                    FatherList1.Show(new Father());
    
                    Action<Son> act = new Action<Father>((Father i) => { });
                }
    
    
                {
                    IMyList<Son, Father> myList1 = new MyList<Son, Father>();
                    IMyList<Son, Father> myList2 = new MyList<Son, Son>();//协变
                    IMyList<Son, Father> myList3 = new MyList<Father, Father>();//逆变
                    IMyList<Son, Father> myList4 = new MyList<Father, Son>();//逆变+协变
                }
            }
        }
    
        public class Father
        {
            public int Id { get; set; }
        }
        public class Son : Father
        {
            public string Name { get; set; }
        }
    
        /// <summary>
        /// 逆变in只能是参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface ICustomerListIn<in T>
        {
            void Show(T t);
        }
    
        public class CustomerListIn<T> : ICustomerListIn<T>
        {
            public void Show(T t)
            {
            }
        }
    
        /// <summary>
        /// out 协变 只能是返回结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface ICustomerListOut<out T>
        {
            T Get();
        }
    
        public class CustomerListOut<T> : ICustomerListOut<T>
        {
            public T Get()
            {
                return default(T);
            }
        }
    
        public interface IMyList<in inT, out outT>
        {
            void Show(inT t);
            outT Get();
            outT Do(inT t);
    
            ////out 只能是返回值   in只能是参数
    
        }
    
        public class MyList<T1, T2> : IMyList<T1, T2>
        {
    
            public void Show(T1 t)
            {
                Console.WriteLine(t.GetType().Name);
            }
    
            public T2 Get()
            {
                Console.WriteLine(typeof(T2).Name);
                return default(T2);
            }
    
            public T2 Do(T1 t)
            {
                Console.WriteLine(t.GetType().Name);
                Console.WriteLine(typeof(T2).Name);
                return default(T2);
            }
        }
    

    相关文章

      网友评论

        本文标题:Unity 基础之 Where约束与协变、逆变

        本文链接:https://www.haomeiwen.com/subject/ojsedftx.html