Jakob Rasmussen
Jakob Rasmussen

Reputation: 191

Returning subtype of IEnumerable in Dictionary not possible

Why is this a problem in C#?

public Dictionary<string, IEnumerable<object>> GetProducts() {
    return new Dictionary<string, IList<object>>();
}

Upvotes: 3

Views: 436

Answers (2)

Kjartan
Kjartan

Reputation: 19151

You can't return this:

new Dictionary<string, IList<object>>();

.. but you can return this:

new Dictionary<string, IEnumerable<object>>();

.. or change your return-type:

public Dictionary<string, IList<object>> GetProducts(){ ... }

Part of the reasoning behind this:

Imagine if you could get the returned Dictionary as a Dictionary<string, IEnumerable<object>>, but with the values as List<object> instead of IEnumerable<object>(where List is a more specific type of IEnumerable).

If you then tried to add a new IEnumerable<object> to it, that would be an invalid operation, since your elements are not, in fact, of type IEnumerable<object>, but rather List<object>.

The reason that is disallowed, is that an element of type List<object> might (and does) contain methods that an IEnumerable<object> does not.

Imagine adding an element of type IEnumerable<object> to a Dictionary<string, List<object>>. That would mean that you could call a List<object>-specific method on each element until you reached the first IEnumerable<object>-element, where that method would not be defined, and therefor throw an exception.

Your original code causes a compile-time error to stop you from ever getting into problems such as this.

I myself asked a related question not too long ago, which might be helpful to understand this better.

Upvotes: 2

Martin Mulder
Martin Mulder

Reputation: 12934

This is not possible, because it would creata a dictionary, having IList<object> as a value.

So if you would call:

IEnumerable<object> values = someOtherObjectCollectionPerhapseSomethingFromLinq;
Dictionary<string, IEnumerable<object>> products = GetProducts();
products.Add("MyKey", values);

Your returning dictionary will accept the IEnumerable<object> but the dictionary underneat will not accept it, since it values HAVE TO BE of type IList<object>, which in this is, it isn't.

Upvotes: 3

Related Questions