Reputation: 3283
I'm writing a couple of extension methods for some of our BusinessObjects
for example:
public static IBusinessObject GetBusinessObjectById<T>(this IBusinessObject businessObject, int id)
Now if i create a class:
public class Topic : IBusinessObject
I can then call my extension:
topic.GetBusinessObjectById<Topic>(id);
However that was the working stuff, now i tried to write a extension which focus on List<IBusinessObject>
:
public static List<T> GetItems<T>(this List<IBusinessObject> list)
then creating a new List:
List<Topic> topics = new List<Topic>();
topics.GetItems<Topic>();
gives the error
List<Topic>
does not contain a definition for GetItems
How can i write an extension method which focuses on a List instance of classes which have implemented my Interface?
Upvotes: 3
Views: 182
Reputation: 292405
A List<Topic>
is not a List<IBusinessObject>
, even though Topic
implements IBusinessObject
; that's because List<T>
is not covariant (and anyway, only interfaces and delegates can be covariant, not classes).
If it was, it could cause all sorts of problems; for instance, consider this (hypothetical) extension method:
public static void Foo(this List<IBusinessObject> list)
{
list.Add(new FooBusinessObject());
}
If you could call this method on a List<BarBusinessObject>
, it would add an object of the wrong type, which would cause an exception at runtime.
If your GetItems
method isn't going to modify the list, it should accept one of these interfaces instead of List<IBusinessObject>
:
IEnumerable<IBusinessObject>
IReadOnlyCollection<IBusinessObject>
IReadOnlyList<IBusinessObject>
All these interfaces are covariant.
Upvotes: 5
Reputation: 12661
An instance of a List<Topic>
is not an instance of a List<IBusinessObject>
. While IEnumerable<T>
is covariant, List<T>
is not.
On the other hand, a List<Topic>
is also an IEnumerable<Topic>
, which is itself an IEnumerable<IBusinessObject>
. Therefore if you redefine your extension method as
public static List<T> GetItems<T>(this IEnumerable<IBusinessObject> collection)
then you should have the function you're looking for.
Upvotes: 1