2014-09-03 119 views
3

我正在寫一對夫婦的擴展方法,對於一些我們的BusinessObjects擴展方法無法識別

例如:

public static IBusinessObject GetBusinessObjectById<T>(this IBusinessObject businessObject, int id) 

現在,如果我創建了一個類:

public class Topic : IBusinessObject 

然後我就可以打電話給我的分機:

topic.GetBusinessObjectById<Topic>(id); 

然而,這是工作的東西,現在我試着寫其中重點List<IBusinessObject>一個延伸:

public static List<T> GetItems<T>(this List<IBusinessObject> list) 

然後創建一個新的列表:

List<Topic> topics = new List<Topic>(); 

topics.GetItems<Topic>();給出了錯誤

List<Topic>不包含GetItems的定義

我該如何編寫一個擴展方法,它着重於實現了我的接口的類的List實例?

+0

我相信那'topics.Cast ().ToList()。GetItems ()'會工作。 – 2014-09-03 08:04:22

+3

http://stackoverflow.com/a/2033921/284240 – 2014-09-03 08:05:23

+1

您可以將參數從List 更改爲IEnumerable ? – Dirk 2014-09-03 08:06:03

回答

5

List<Topic>一個List<IBusinessObject>,即使Topic實現IBusinessObject;這是因爲List<T>不是covariant(並且無論如何,只有接口和委託可以是協變的,而不是類)。

如果是這樣,它可能會導致各種問題;例如,考慮這個(假設)擴展方法:

public static void Foo(this List<IBusinessObject> list) 
{ 
    list.Add(new FooBusinessObject()); 
} 

如果你可以調用一個List<BarBusinessObject>這個方法,它會增加錯誤的類型,這將在運行時會導致異常的對象。

如果您GetItems方法不會修改列表,它應該接受這些接口中的一個,而不是List<IBusinessObject>

  • IEnumerable<IBusinessObject>
  • IReadOnlyCollection<IBusinessObject>
  • IReadOnlyList<IBusinessObject>

所有這些接口是協變的。

+0

+1解釋爲什麼'List '不是協變的。我以前沒有見過。 – 2014-09-03 08:12:48

+0

感謝您的解釋! – Mark 2014-09-03 08:17:51

1

List<Topic>的實例不是List<IBusinessObject>的實例。雖然IEnumerable<T>是協變的,但是List<T>不是。

另一方面,List<Topic>也是IEnumerable<Topic>,其本身是IEnumerable<IBusinessObject>。因此,如果你重新定義你的擴展方法爲

public static List<T> GetItems<T>(this IEnumerable<IBusinessObject> collection) 

那麼你應該有你正在尋找的功能。

相關問題