Extension method for list <InterfaceType> is not recognized

I am writing a couple of extension methods for some of our BusinessObjects

eg:

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

      

Now if I create a class:

public class Topic : IBusinessObject

      

Then I can call the extension:

topic.GetBusinessObjectById<Topic>(id);

      

However this was working material, now I tried to write an extension that focuses on List<IBusinessObject>

:

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

      

and then create a new list:

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

      

topics.GetItems<Topic>();

gives error

List<Topic>

does not contain a definition for GetItems

How can I write an extension method that focuses on the List instance of the classes that implemented my interface?

+3


source to share


2 answers


A List<Topic>

is not List<IBusinessObject>

, though Topic

implements IBusinessObject

; because List<T>

not covariant (and in any case, only interfaces and delegates can be covariant, not classes).

If that were the case, it could cause all sorts of problems; for example, consider this (hypothetical) extension method:

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

      

If you can call this method on List<BarBusinessObject>

, it will add an object of the wrong type, which will throw a runtime exception.



If your method GetItems

doesn't change the list, it should accept one of these interfaces instead List<IBusinessObject>

:

  • IEnumerable<IBusinessObject>

  • IReadOnlyCollection<IBusinessObject>

  • IReadOnlyList<IBusinessObject>

All of these interfaces are covariant.

+5


source


An instance is List<Topic>

not an instance List<IBusinessObject>

. While IEnumerable<T>

covariant, List<T>

it is not.

On the other hand, a is List<Topic>

also IEnumerable<Topic>

, which itself is IEnumerable<IBusinessObject>

. So if you change your extension method as



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

      

then you should have the function you are looking for.

+1


source







All Articles