我正在为一些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 :(得分: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)
那么你应该拥有你正在寻找的功能。