2014-04-01 20 views
0

我不斷看到此錯誤,一遍又一遍:C#拒絕接受通用的子類型

無法轉換從Item<Foo>Item<IFoo>

這顯然是無稽之談; Item<Foo>類型的對象是靜態保證能夠完成Item<IFoo>可以做的所有事情(可能還有更多),那麼爲什麼編譯器拒絕接受我完全有效的代碼呢?

我有一個方法接受Item<IFoo>作爲參數。出於某種原因,它拒絕接受Item<Foo>作爲輸入,即使Foo實施了IFoo。這完全沒有意義。我可以通過Foo代替IFoo,但我無法通過Item<Foo>代替Item<IFoo>。爲什麼?

public class Item<T> 
{ 
    public readonly int ID; 
    public readonly T Data; 
    ... 
} 

public void ProcessItem(Item<IFoo> item) 
{ 
    Console.WriteLine(item.ID); 
} 

ProcessItem(new Item<Foo>()); 
+2

你能顯示你的代碼嗎? –

+0

聽起來像[協方差](http://msdn.microsoft.com/en-us/library/ee207183.aspx)問題。您使用的是什麼版本的.NET,並且可以顯示拋出此錯誤的代碼? –

+1

'Item'有點像List嗎? –

回答

3

類在C#中是不變的,所以要根據您的要求,你必須創建一個接口和implment是:

public interface IItem<out T> { ... } 
public class Item<T> : IItem<T> { ... } 

IItem<IFoo> item = new Item<Foo>(); 

注意,它不一定是安全的分配Class<Subtype>Class<Basetype>。一個常見的例子是List<T>

List<object> l = new List<string>(); //won't compile 
l.Add(3); 

C#只允許在接口和委託方的註解,只有當它是安全的這樣做。

+0

我想這裏的「正確」解決方案是完全放棄泛型,只是將參數硬編碼爲「IFoo」......我假定泛型能夠理智地工作。我猜不會。 – MathematicalOrchid