为了账号安全,请及时绑定邮箱和手机立即绑定

传递带有约束的泛型类型作为 Type<Constraint>

传递带有约束的泛型类型作为 Type<Constraint>

C#
繁花不似锦 2021-06-04 13:25:29
如果我GenericClass的类型约束为where T : BaseType,为什么我不能将其作为 传递GenericClass<BaseType>?class GenericClass<T> where T : BaseType{    void Method()    {        new UtilityClass().Method(this);    }}class UtilityClass{    internal void Method(GenericClass<BaseType> genericClass)    {    }}静态分析器错误:Cannot convert from 'GenericsPoc.GenericClass<T>' to 'GenericsPoc.GenericClass<GenericsPoc.BaseType>'我没想到这一点,因为UtilityClass<T>在T具有继承BaseClass。
查看完整描述

2 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

您需要进行修改,UtilityClass以便该方法也向下传递泛型类型:


internal void Method<T>(GenericClass<T> genericClass) where T: BaseType

{

}


查看完整回答
反对 回复 2021-06-05
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

这个问题每天都会被问到。再一次!


class Cage<T> where T : Animal

{

  public void Add(T t) { ... }

}

现在你的问题是:为什么这是非法的?


Cage<Animal> cage = new Cage<Gerbil>();

因为这一行是合法的:


cage.Add(new Tiger());

Cage<Animal>有一个方法Add,它需要Animal. ATiger是 anAnimal所以必须是合法的。但这意味着我们只是将老虎放入沙鼠笼中。


由于该行必须是合法的并且会导致类型错误,因此其他一些行必须是非法的,现在您知道它是哪一行了。


你想要的特性称为泛型协方差,它在 C# 中是合法的,当:


泛型类型是接口或委托

可变类型参数是引用类型

接口或委托已被标记为安全的变化。

例如:


IEnumerable<Animal> animals = new List<Tiger>() { new Tiger() };

那是合法的。List<Tiger>implements IEnumerable<Tiger>,它是一个接口并标记为协方差安全,因此可以将其分配给IEnumerable<Animal>。


您会注意到无法将鸭子放入动物序列中,因此无法将鸭子放入老虎序列中。这就是我们如何知道协方差是安全的。


查看完整回答
反对 回复 2021-06-05
  • 2 回答
  • 0 关注
  • 165 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信