C# 列表的扩展方法<;接口类型>;不被承认

C# 列表的扩展方法<;接口类型>;不被承认,c#,extension-methods,C#,Extension Methods,我正在为我们的一些BusinessObjects编写一些扩展方法 例如: public static IBusinessObject GetBusinessObjectById<T>(this IBusinessObject businessObject, int id) 然后我可以呼叫我的分机: topic.GetBusinessObjectById<Topic>(id); topic.GetBusinessObjectById(id); 然而,这是有效的东西,现

我正在为我们的一些BusinessObjects编写一些扩展方法

例如:

public static IBusinessObject GetBusinessObjectById<T>(this IBusinessObject businessObject, int id)
然后我可以呼叫我的分机:

topic.GetBusinessObjectById<Topic>(id);
topic.GetBusinessObjectById(id);
然而,这是有效的东西,现在我试图编写一个扩展,重点放在
List

公共静态列表GetItems(此列表)
然后创建一个新列表:

List<Topic> topics = new List<Topic>();
列表主题=新建列表();
topics.GetItems()给出了错误

列表
不包含GetItems的定义

我如何编写一个扩展方法来关注实现了我的接口的类的列表实例?

a
List
不是
List
,即使
Topic
实现了
IBusinessObject
;这是因为
List
不是(无论如何,只有接口和委托可以是协变的,而不是类)

如果是的话,它可能会引起各种各样的问题;例如,考虑这个(假设的)扩展方法:

public static void Foo(this List<IBusinessObject> list)
{
    list.Add(new FooBusinessObject());
}
publicstaticvoidfoo(此列表)
{
添加(新的FooBusinessObject());
}
如果您可以在
列表上调用此方法,它将添加错误类型的对象,这将在运行时导致异常

如果您的
GetItems
方法不打算修改列表,它应该接受这些接口之一,而不是
list

  • IEnumerable
  • IReadOnlyCollection
  • IReadOnlyList

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

列表的实例
不是列表的实例。虽然
IEnumerable
是协变的,
List
不是协变的

另一方面,
列表
也是一个
IEnumerable
,它本身就是一个
IEnumerable
。因此,如果将扩展方法重新定义为

public static List<T> GetItems<T>(this IEnumerable<IBusinessObject> collection)
公共静态列表GetItems(此IEnumerable集合)

那么你应该拥有你正在寻找的函数。

我相信
topics.Cast().ToList().GetItems()
可以工作。你能将参数从
List
更改为
IEnumerable
?@pwas吗,
topics.ToList()
更简单,也同样可以工作;)+1解释为什么
列表
不是协变的。我以前没见过。谢谢你的解释!
public static void Foo(this List<IBusinessObject> list)
{
    list.Add(new FooBusinessObject());
}
public static List<T> GetItems<T>(this IEnumerable<IBusinessObject> collection)