5

My C# skills are low, but I can't understand why the following fails:

public interface IQuotable {} public class Order : IQuotable {} public class Proxy { public void GetQuotes(IList<IQuotable> list) { ... } } 

Then the code is as follows:

List<Order> orders = new List<Orders>(); orders.Add(new Order()); orders.Add(new Order()); Proxy proxy = new Proxy(); proxy.GetQuotes(orders); // produces compile error 

Am I simply doing something wrong and not seeing it? Since Order implements Quotable, a list of order would go in as IList of quoatables. I have something like in Java and it works, so I'm pretty sure its my lack of C# knowledge.

2 Answers 2

12

You can't convert from a List<Order> to an IList<IQuotable>. They're just not compatible. After all, you can add any kind of IQuotable to an IList<IQuotable> - but you can only add an Order (or subtype) to a List<Order>.

Three options:

  • If you're using .NET 4 or higher, you can use covariance if you change your proxy method to:

    public void GetQuotes(IEnumerable<IQuotable> list) 

    This only work if you only need to iterate over the list, of course.

  • You could make GetQuotes generic with a constraint:

    public void GetQuotes<T>(IList<T> list) where T : IQuotable 
  • You could build a List<IQuotable> to start with:

    List<IQuotable> orders = new List<IQuotable>(); orders.Add(new Order()); orders.Add(new Order()); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! My thinking always was List is concrete implementation of IList. Order is the same (but there could be more IQuotables of course. So I can pass anything into method as long as they implement IList with IQuotable. Obviously that is not the case so I have to read up on covariance. I'm using .net 2 because this is a CLR stored procedure which take .net 2 only. In the end, I've used your 2nd example which, I think, makes sense and does what exactly what I need.
9

IList is not covariant. You can't cast a List<Order> to an IList<Quotable>.

You can change the signature of GetQuotes to:

public void GetQuotes(IEnumerable<IQuotable> quotes) 

Then, materialize a list (if you need its features), through:

var list = quotes.ToList(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.