【C#】【溫故知新】委託與接口中泛型的協變與逆變

public class Test : MonoBehaviour
{
    //協變,out修飾返回值
    public delegate T Function<out T>();
    //逆變,in修飾傳入參數
    public delegate void Action<in T>(T t);

    public class Animal { }
    public class Dog : Animal { }

    private void Start()
    {
        //成立。方法DogFunc與委託function1的返回值類型相同
        Function<Dog> function1 = DogFunc;
        //成立。方法DogFunc的返回值是委託function2的返回值的子類,要求返回父類型時返回子類型,符合賦值兼容性的原則
        Function<Animal> function2 = DogFunc;
        //普通情況下不成立,協變下成立。
        //普通情況下,function1與function3都是delegate的子類,是同級的,沒有繼承關係,不符合賦值兼容性的原則
        //協變,在委託或接口中,返回值是基類時允許返回其子類,允許更高程度的子類型處於返回及輸出位置
        Function<Animal> function3 = function1;

        Debug.Log(function1());     // Dog
        Debug.Log(function2());     // Dog
        Debug.Log(function3());     // Dog

        //----------

        //成立。方法AnimalAct與委託action1的參數類型相同
        Action<Animal> action1 = AnimalAct;
        //成立。委託action2的參數類型是方法AnimalAct的參數類型子類,要求傳入父類型時傳入子類型,符合賦值兼容性的原則
        Action<Dog> action2 = AnimalAct;
        //普通情況下不成立,逆變下成立。
        //普通情況下,action1與action3都是delegate的子類,是同級的,沒有繼承關係,不符合賦值兼容性的原則
        //逆變,在委託或接口中,在期望傳入基類型是允許傳入其子類型,允許更高程度的子類型作爲輸入參數
        Action<Dog> action3 = action1;

        action1(new Animal());      // Animal
        action2(new Dog());         // Dog
        action3(new Dog());         // Dog
    }

    private Dog DogFunc()
    {
        return new Dog();
    }

    private void AnimalAct(Animal animal)
    {
        Debug.Log(animal);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章