Tom Hamming
Tom Hamming

Reputation: 10961

Interface Polymorphism in C# 2.0

Say I've got this interface:

public interface IFoo
{
   string Text {get;}
}

And this class that implements it:

public class Bar : IFoo
{
   public string Text
   {
      get {return "Hello World!";}
   }
}

I've got a function that takes as an argument a List<IFoo>. When I try to pass it a List<Bar>, I get this compiler error:

Argument 1: cannot convert from System.Collections.Generic.List<Bar>
to System.Collections.Generic.List<IFoo>

Why is this? It seems like that should work for the same reason as if I passed a list of a class that inherits from Bar directly.

Upvotes: 4

Views: 512

Answers (3)

Yuriy Faktorovich
Yuriy Faktorovich

Reputation: 68667

Because generic contravariance was not supported in .Net 2.0. You can do it with arrays though.

IFoo[] foos = new Bar[5];

Another option is to do

List<IFoo> myList = myBarList.ConvertAll(b => (IFoo)b);

Upvotes: 4

Adriano Carneiro
Adriano Carneiro

Reputation: 58595

Do not pass List<Bar>. Use cast and pass this:

yourObj.YourMethod(yourListOfBar.Cast<IBar>().ToList());

Upvotes: 1

jason
jason

Reputation: 241611

Why is this? It seems like that should work for the same reason as if I passed a list of a class that inherits from Bar directly.

Because this disaster can happen:

class EvilBar : IFoo { }

List<Bar> list = new List<Bar>();
List<IFoo> foos = list; // suppose it were allowed
foos.Add(new EvilBar());

And now you've add an EvilBar to a list than can only accept Bar. Oops!

Basically, you've discovered that T -> List<T> is not covariant in T.

Upvotes: 10

Related Questions