csharp

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

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

示例

Play函数传入的参数必须满足
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();

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

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

相应全部代码
    /// <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);
        }
    }
上一篇下一篇

猜你喜欢

热点阅读