关于C#中的协变和逆变

协变和逆变是一个不太好理解的东西。
简单说,泛型委托希望在类型定义上能够通用基类和派生类,即用基类(派生类)类型定义的泛型变量,可以赋值给用派生类(基类)定义的泛型变量,实现互通互用。
一、协变只能用在返回值上,delegate T Func <out T> ();
如果我们定义一个基类一个派生类:

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

那么派生类委托变量赋值给基类委托变量是可以的:

delegate  T Func <out T> ();
static void Main(string[] args)
{
   Func<Dog> makedog = Makedog;
   Func<Animal> makeanimal = makedog;
   makeanimal();
}
static Dog Makedog()
{
   Console.WriteLine("success!");
   return new Dog();
}

但基类委托变量反过来不能赋值给派生类委托变量:

delegate  T Func <out T> ();
static void Main(string[] args)
{
    Func<Animal> makeanimal = MakeAnimal;
    Func<Dog> makedog = makeanimal;//编译错误
    makedog();
}
static Animal  MakeAnimal()
{
    Console.WriteLine("success!");
    return new Dog();
}

二、逆变只能用在参数上,delegate void Func <in T> (T para);
和协变相反,基类委托变量可以赋值给派生类变量:

delegate void Func<in T>(T a);
static void Main(string[] args)
{
    Func<Animal> makeanimal= MakeAnimal;
    Func<Dog> makedog = makeanimal;
    makedog(new Dog());           
}
static void MakeAnimal(Animal a)
{
    Console.WriteLine("success!");        
}

但派生类委托变量不能赋值给基类委托变量。

delegate void Func<in T>(T a);
static void Main(string[] args)
{
    Func<Dog> makedog = Makedog;
    Func<Animal> makeanimal = makedog;//编译错误
    makeanimal(new Animal());
}
static void Makedog(Dog a)
{
    Console.WriteLine("success!");
}

三、不可能在一个类型定义上同时使用协变和逆变

delegate T Func< out T> (T para);//编译错误
delegate T Func< in T> (T para);//编译错误

只能分别定义:

delegate T Func< out T,in S> (S para);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值