1

I have an abstract class with a few inheriting classes like so:

internal abstract class SomeBaseType {}
internal class FirstSpecificType : SomeBaseType {}
internal class SecondSpecificType : SomeBaseType {}
internal class ThirdSpecificType : SomeBaseType {}

and a class with a constrained generic type parameter:

internal class SomeCollection<T> : ICollection<SomeDataStructure>
    where T : SomeBaseType {}

I created a List<SomeCollection<SomeBaseType>> and tried to add elements of various inheriting classes of SomeBaseType but I get the following errors (CS1503 and CS1950):

Argument 1: cannot convert from 'Namespace.SomeCollection<FirstSpecificType>' to 'Namespace.SomeCollection<SomeBaseType>'
The best overloaded Add method 'List<SomeCollection<SomeBaseType>>.Add(SomeCollection<SomeBaseType>)' for the collection initializer has some invalid arguments

Since FirstSpecificType is a SomeBaseType, I should be able to do this, right? It's basically the same as adding some arbitrary set of object to an IList<object>.


For additional context, the code where this error manifests looks like this:

protected Constructor()
{
    collectionOne = new SomeCollection<FirstSpecificType>();
    collectionTwo = new SomeCollection<SecondSpecificType>();
    collectionThree = new SomeCollection<ThirdSpecificType>();

    allCollections = new List<SomeCollection<SomeBaseType>>
    {
        // Each of these three collections has the error
        collectionOne,
        collectionTwo,
        collectionThree
    };
}
2
  • That's covariance and covariance on generic classes doesn't work. Commented Mar 1, 2016 at 21:55
  • 2
    This question is asked every day. One more time: a list of giraffes is not a list of animals. Why? Because you can put a tiger into a list of animals but not into a list of giraffes. A list of animals is not a list of giraffes. Why? Because there might already be a tiger inside the list of animals. Therefore a list of giraffes and a list of animals are never compatible, because the operations you can do on those two types are different. The fact that some animals are giraffes is irrelevant. Commented Mar 2, 2016 at 0:29

1 Answer 1

1

This is an issue of covariance and contravariance, that basically says that while FirstSpecificType is indeed SomeBaseType, SomeCollection<FirstSpecificType> is strictly not SomeCollection<SomeBaseType>.

Eric Lippert wrote some fabulous articles about this and giraffes that I'd recommend everybody to read at least once :-)

Sign up to request clarification or add additional context in comments.

3 Comments

John Skeet wrote some fabulous articles... ... Why not link that article as well?
@Rahul - when mixing up .net guru's, it's hard to find the right link ;-)
Thanks for the explanation and links, @Amit. That helped me figure out a new way to my goal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.