2008-10-09 42 views
3

我試圖向他人展示他們創建的瘋狂情況下的界​​面使用。它們在列表中有幾個不相關的對象,並且需要對每個對象的兩個字符串屬性執行操作。我指出,如果他們將屬性定義爲接口的一部分,他們可以使用接口對象作爲作用於其上的方法參數的類型;例如:有沒有辦法將通用列表轉換爲接口/基類類型列表?

void PrintProperties(IEnumerable<ISpecialProperties> list) 
{ 
    foreach (var item in list) 
    { 
     Console.WriteLine("{0} {1}", item.Prop1, item.Prop2); 
    } 
}

這似乎是這一切都很好,但需要對工作的名單都沒有(也不應該)與接口的類型參數聲明。但是,它似乎並不像您可以投射到不同的類型參數。例如,這個失敗,我不明白爲什麼:

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Test> myList = new List<Test>(); 
      for (int i = 0; i < 5; i++) 
      { 
       myList.Add(new Test()); 
      } 

      PrintList((IEnumerable<IDoSomething>)myList); 
     } 

     static void PrintList(IEnumerable<IDoSomething> list) 
     { 
      foreach (IDoSomething item in list) 
      { 
       item.DoSomething(); 
      } 
     } 
    } 

    interface IDoSomething 
    { 
     void DoSomething(); 
    } 

    public class Test : IDoSomething 
    { 
     public void DoSomething() 
     { 
      Console.WriteLine("Test did it!"); 
     } 
    } 
}

可以使用Enumerable.Cast<T>成員要做到這一點,但我一直在尋找可能的工作在.NET 2.0和方法。看來這應該是可能的;我錯過了什麼?

回答

5

的問題與方法,而不是與它怎麼叫.....

void PrintProperties<SP>(IEnumerable<SP> list) where SP: ISpecialProperties 
{ 
    foreach (var item in list) 
    { 
     Console.WriteLine("{0} {1}", item.Prop1, item.Prop2); 
    } 
} 
+0

正是我剛寫的東西。 – 2008-10-09 19:24:27

+0

我偶然發現它,並且也要發佈它。這有點奇怪,但我可以理解爲什麼它是這樣;你必須指定類型是可施放的。 – OwenP 2008-10-09 19:25:22

5

失敗的原因是因爲仿製藥並不在C#中(還)表現出差異。

而對於修爲的IEnumerable < T>,不過,試試這個:

public static IEnumerable<TBase> SafeConvert<TBase, TDerived>(IEnumerable<TDerived> source) 
    where TDerived : TBase 
{ 
    foreach (TDerived element in source) 
    { 
     yield return element; // Implicit conversion to TBase 
    } 
} 

編輯:現有的其他答案是比上述的這種特殊情況比較好,但我會離開這裏這是如果你確實需要「轉換」序列,這是一個非常有用的東西。

+0

啊Skeet先生 - 非常棒的例子,非常幫助我,謝謝! – BenAlabaster 2009-01-29 00:29:37

1

您可以在列表中使用foreachforeach做內置演員。所以,如果你把循環出來的功能,你可以寫類似

List<Test> myList = new List<Test>(); 
for (int i = 0; i < 5; i++) 
{ 
    myList.Add(new Test()); 
} 

foreach (IDoSomething item in myList) 
{ 
    item.DoSomething(); 
} 
+0

需要注意的一點(在foreach中強制轉換),但並不涉及將各種派生類型的列表傳遞給同一函數以防函數必須執行其他操作。 – 2008-10-09 21:12:25

-1

這不回答你的問題(或我猜:)鍛鍊的觀點,但我只是使用反射在這通過將特殊屬性附加到感興趣的屬性。

相關問題