Reputation: 29227
I have the following code:
class Header<TItem> where TItem : IItem { IEnumerable<TItem> Item { get; set; } }
class HeaderA : Header<ItemA> { public HeaderA(int a) {...} }
class HeaderB : Header<ItemB> { public HeaderB(int b) {...} }
interface IItem {...}
class ItemA : IItem { }
class ItemB : IItem { }
public static List<Header<IItem>> list = new List<Header<IItem>>
{
new HeaderA(1)
}
The compile error on the last new HeaderA(1)
is
Error 1 The best overloaded Add method
'System.Collections.Generic.List<NS.Header<NS.IItem>>.Add(NS.Header<NS.IItem>)'
for the collection initializer has some invalid arguments
How to fix the issue?
Upvotes: 0
Views: 139
Reputation: 1503499
You're trying to add a Header<ItemA>
to a List<Header<IItem>>
. That requires a conversion from Header<ItemA>
to Header<IItem>
- and that conversion doesn't exist. It doesn't exist for a good reason. Imagine your code was valid... then this would work:
List<Header<IItem>> list = ...; // As per code
Header<IItem> header = list[0];
header.Item = new List<IItem>();
Now remember that header
is actually a HeaderA
- so this working is equivalent to this
HeaderA header = new HeaderA();
header.Item = new List { new ItemB() };
That's not good when anything else would expect header.Item
to be an IEnumerable<ItemA>();
- so this should be okay:
ItemA itemA = header.Item.First();
... and clearly won't if you've added an ItemB
in there.
Basically, you're looking for generic covariance - but you can only declare that on interfaces and delegates (not on classes such as Header<TItem>
), and only when the type parameter isn't used in an input position as it is here due to the Item
setter.
Perhaps more importantly, your design looks extremely complicated - I strongly suspect that if you take a step back, you can design your way around trying to do this in the first place.
Upvotes: 7