C# 入门(13) 泛型(generic)、协变(convariance)、逆变(contravariance)

C#的泛型、协变、逆变

参考书籍: 《C#图解教程》

  泛型是个好东西。很多模版类都用到泛型。


约束(constrain)类型和次序

  可以约束泛型,但有特定的顺序。在类后面加where 关键字

  • 越详细的约束应该放在越靠前的地方。
  • 可以有任意多个接口约束。
  • 如果有构造函数约束,放在最后。

泛型约束

约束顺序


如果泛型方法接受一个同类型参数,可以省略尖括号。

//类型参数 和 方法参数类型 相同。
public void MyMethod<T> (T value) {...}

int myValue = 666;
MyMethod<int>(myValue);
MyMethod(myValue);                //等价与上一句

泛型接口的实现必须唯一。在实现泛型接口时,要保证类型实参组合不会产生两个一样的接口。看如下代码:

interface IMyIfc<T> {}

class MyClass<S> : IMyIfc<int> , IMyIfc<S>   //错误!!因为S可能是int类型。
{
}

协变

  对于泛型来说,想要把子类分配给父类的变量,就要用到协变。看代码:

class Animal { public int Legs = 4; }
    class Dog : Animal { }

    delegate T Factory<T>();

    class Program2
    {
        static Dog MakeDog() { return new Dog(); }

        static void Main(string[] args)
        {
            Factory<Dog> dogMaker = MakeDog;
            Factory<Animal> animalMaker = dogMaker;     //报错,无法隐式转换

            Console.WriteLine(animalMaker().Legs.ToString());
            Console.ReadLine();
        }
    }

尽管Dog是Animal的子类,但Factory< Dog >并不是Factory< Animal>的子类,所以无法进行转换。这时候用协变就好了(添加out 关键字)。

    delegate T Factory<out T>();   //out指定了类型参数的协变。

逆变

  和协变相似,逆变用 in 关键字指定类型参数。是从基类赋值给派生类。


协变和逆变总结

协变和逆变比较

显式变化使用in和out关键字只适用于委托和接口,不适用于类、结构和方法。


可以参考别人家的博客:对协变和逆变的简单理解
协变逆变总结

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值