2009-10-07 54 views
2

我想上傳一個作爲對象(這是IEnumerable類型的對象的upcast)傳遞給IEnumerable的參數,其中Foo實現IFoo。如果將IEnumerable類型爲<Foo>的對象上傳到IEnumerable <IFoo>(如果作爲對象傳遞給該函數)?

這是我想要做的一個例子,但它不起作用。

public void F(object o) 
{ 
    //I know the object o is of type IEnumerable<Foo> where Foo implements IFoo 
    IEnumerable<IFoo> ifoos = (IEnumerable<IFoo>) o); 
} 

是否有解決方法?我不想讓函數F美孚具體,但我不能讓它的內容投射到界面,除非我做的:

IEnumerable<IFoo> ifoos = (IEnumerable<Foo>) o).Select(f => (IFoo) f); 

感謝

朱塞佩

回答

10

.NET 4.0,你可以之前't - IEnumerable<T>在.NET 4.0之前是不變的

使用.NET 4.0,您發佈的代碼將正常工作。

在.NET 3.5,你可以使用Enumerable.Cast

public void F(object o) 
{ 
    IEnumerable<IFoo> ifoos = ((IEnumerable) o).Cast<IFoo>(); 
} 

這基本上採用弱類型IEnumerable(兩者IEnumerable<Foo>IEnumerable<IFoo>延長,所以劇組將被罰款),然後應用Cast<T>方法,該方法將基本上鍊接另一個迭代器在每個項目上執行強制轉換。如果Foo : IFoo這個演員肯定會工作,所以你會沒事的。

在.NET 2.0,你不得不自己寫基本Cast,這是很容易 - 特別是如果你不需要做任何的快捷鍵:

public static IEnumerable<TResult> Cast<TSource, TResult> 
    (IEnumerable<TSource> source) 
{ 
    foreach(TSource item in source) 
    { 
     yield return (TResult) (object) item; 
    } 
} 

雙投是略顯尷尬,但它的工作原理...

+0

有關.NET 4協方差/逆變的更多信息:http://msdn.microsoft.com/en-us/library/dd233054%28VS.100%29.aspx及底部表格中的相關主題。 – 2009-10-07 11:18:42

+0

或者通過深入閱讀C#的第二版,並閱讀第13章:)(http://manning.com/skeet2) – 2009-10-07 11:19:18

+0

難以置信的快速回復,點擊謝謝! – 2009-10-07 11:29:58

1

一般的方法是可以接受的嗎?

interface IFoo { } 
class Foo : IFoo { } 
static void F<T>(IEnumerable<T> data) where T : IFoo 
{ 
    foreach(T item in data) { 
     // compiler knows that `item` is an `IFoo` etc 
    } 
} 

... 
List<Foo> foos = new List<Foo>(); 
F(foos); 

否則;等到.NET 4.0/C#4.0/VS2010。

+0

它會如果我創建的功能從頭開始,但我正在調整現有函數的主體,以便它可以處理實現IFoo的其他類型。 – 2009-10-07 11:33:11

相關問題