简体   繁体   English

为什么不能将一个受约束的开放泛型类型转换为受约束类型?

[英]Why can't you cast a constrained open generic typed to the constrained type?

I think I must be missing something, why can't I compile this:我想我一定遗漏了一些东西,为什么我不能编译这个:

class Foo<T> where T : Bar
{
    T Bar;
}

abstract class Bar
{ }

class MyBar : Bar
{ }

static void Main(string[] args)
{
    var fooMyBar = new Foo<MyBar>();
    AddMoreFoos(fooMyBar);
}

static void AddMoreFoos<T>(Foo<T> FooToAdd) where T : Bar
{
    var listOfFoos = new List<Foo<Bar>>();
    listOfFoos.Add(FooToAdd); //Doesn't compile
    listOfFoos.Add((Foo<Bar>)FooToAdd); //doesn't compile
}

You're make things a little bit more confusing than they need to be by using a list here... it's easiest to see the effect this way:通过在此处使用列表,您会使事情变得比需要的更混乱......这样最容易看到效果:

// This won't compile
Foo<Bar> fooBar = new Foo<MyBar>();

Given that this doesn't compile, it's then not surprising that you can't add a Foo<MyBar> to a List<Foo<Bar>>鉴于这无法编译,因此您不能将Foo<MyBar>添加到List<Foo<Bar>>也就不足为奇了

So why isn't a Foo<MyBar> a Foo<Bar> ?那么为什么Foo<MyBar>不是Foo<Bar>呢? Because generic classes aren't covariant.因为泛型类不是协变的。

Generic variance was only introduced in C# 4 - and it only works for interfaces and delegates.泛型变量仅在 C# 4 中引入 - 它仅适用于接口和委托。 So you could (in C# 4) do:所以你可以(在 C# 4 中)这样做:

IEnumerable<MyBar> x = new List<MyBar>();
IEnumerable<Bar> y = x;

but you couldn't do:但你不能这样做:

IList<MyBar> x = new List<MyBar>();
IList<Bar> y = x;

I have a whole talk about variance which you can download from the NDC 2010 video site - just search for "variance".我有一个完整的关于方差的讨论,您可以从NDC 2010 视频网站下载 - 只需搜索“方差”。

It doesn't compile because if you were to call your method with a Foo<int> then the call will fail: you are trying to assume a specific type for your generic parameter.它无法编译,因为如果您要使用Foo<int>调用您的方法,那么该调用将失败:您正试图为泛型参数假定特定类型。

What you need is to use var listOfFoos = new List<Foo<T>>() instead, then the Add should work.您需要使用var listOfFoos = new List<Foo<T>>()代替,然后Add应该可以工作。

(EDIT: equally, the cast would work if you used Foo<T> - but you still can't assume in your code that T is Bar ). (编辑:同样,如果您使用Foo<T> ,演员也会起作用 - 但您仍然不能在您的代码中假设TBar )。

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

相关问题 为什么我不能将对象强制转换为约束泛型? - Why can't I cast an object to a constrained generic? 为什么我不能将&#39;as&#39;用于限制为接口的泛型类型参数? - Why can't I use 'as' with generic type parameter that is constrained to be an interface? 将Type转换为Generic约束T - Convert a Type to a Generic constrained T 类型约束C#Generic的无效转换 - Invalid Cast of Type Constrained C# Generic 为什么我必须强制转换为类型参数,而不能使用受约束的类型? - Why do I have to cast to type parameter and can't use the constrained type? 为什么在测试受约束的泛型类型时直接强制转换失败但“as”运算符成功? - Why does a direct cast fail but the “as” operator succeed when testing a constrained generic type? 如何使用带有强制转换的泛型参数(限制为整数类型)实现方法? - How can I implement a method with a generic parameter (constrained to an integer type) with a cast? 约束泛型类型参数的逆解 - Contravariance on constrained generic type parameters 约束通用类型参数的继承 - Inheritance on a constrained generic type parameter 当使用相互约束的类型参数调用通用扩展方法时,不能省略扩展类型参数 - Can't omit the extension type argument when calling generic extension method with mutually constrained type parameters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM