繁体   English   中英

以约束作为类型传递通用类型<Constraint>

[英]Passing Generic Type with Constraint as Type<Constraint>

如果我的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>'

我没想到这一点,因为T必须从BaseClass继承UtilityClass<T>

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

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 TigerAnimal因此必须合法。 但这意味着我们只是将老虎放入沙鼠笼中。

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

所需的功能称为通用协方差,并且在以下情况下在C#中合法:

  • 泛型类型是接口或委托
  • 变量类型参数是引用类型
  • 接口或委托已被标记为可以安全使用。

例如:

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

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

您会注意到, 没有办法将鸭子放入一系列动物中 ,因此也没有办法将鸭子放入一系列老虎中。 这就是我们知道协方差是安全的

您需要修改UtilityClass以便该方法还可以传递通用类型:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM