无法识别List <interfacetype>的扩展方法</interfacetype>

时间:2014-09-03 08:02:23

标签: c# extension-methods

我正在为一些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实例?

2 个答案:

答案 0 :(得分: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>

所有这些接口都是协变的。

答案 1 :(得分: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)

那么你应该拥有你正在寻找的功能。