[英]Why can't you cast a constrained open generic typed to the constrained type?
我想我一定遺漏了一些東西,為什么我不能編譯這個:
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
}
通過在此處使用列表,您會使事情變得比需要的更混亂......這樣最容易看到效果:
// This won't compile
Foo<Bar> fooBar = new Foo<MyBar>();
鑒於這無法編譯,因此您不能將Foo<MyBar>
添加到List<Foo<Bar>>
也就不足為奇了
那么為什么Foo<MyBar>
不是Foo<Bar>
呢? 因為泛型類不是協變的。
泛型變量僅在 C# 4 中引入 - 它僅適用於接口和委托。 所以你可以(在 C# 4 中)這樣做:
IEnumerable<MyBar> x = new List<MyBar>();
IEnumerable<Bar> y = x;
但你不能這樣做:
IList<MyBar> x = new List<MyBar>();
IList<Bar> y = x;
我有一個完整的關於方差的討論,您可以從NDC 2010 視頻網站下載 - 只需搜索“方差”。
它無法編譯,因為如果您要使用Foo<int>
調用您的方法,那么該調用將失敗:您正試圖為泛型參數假定特定類型。
您需要使用var listOfFoos = new List<Foo<T>>()
代替,然后Add
應該可以工作。
(編輯:同樣,如果您使用Foo<T>
,演員也會起作用 - 但您仍然不能在您的代碼中假設T
是Bar
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.