Click here to Skip to main content
15,895,740 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. I was experimenting with the concept of Covariance in Generic interfaces and I came across something that I want to ask you about
I know that this code won't work:
C#
List<Base> randomList = new List<Derived>();

It doesn't work because they differ in their generic parameters.

This code also won't work:
C#
IList<Derived> derived = new List<Derived>();
            IList <Base> basee = derived;


But if I do a cast:
C#
IList <Base> basee = (IList<Base>)derived;

The compiler won't complain. I know that it will fail at runtime because Lists don't support covariance but here i'm asking about why this cast is allowed.
What does the compiler look at when deciding whether a cast is allowed or not?

What I have tried:

Tried to find the answer in Microsoft Docs but they haven't talked about explicit casting in terms of Generics.
Posted
Updated 8-Apr-18 21:45pm

1 solution

Quote:
It doesn't work because they differ in their generic parameters.

I don't understand above statement. Nevertheless...

In a short: You cannot create a list of base class by passing new list of derived class! You have to explicit convert derived class into base class:
C#
List<MyDerived> derivedList = new List<MyDerived>();
derivedList.Add(new MyDerived("a"));
derivedList.Add(new MyDerived("b"));
List<MyBase> baseList = derivedList.Cast<MyBase>().ToList();
//you can add MyDerived class without casting, because of its base class ;)
baseList.Add(new MyDerived("c"));


Please, refer these for further details:
base (C# Reference) | Microsoft Docs[^]
Casting and Type Conversions (C# Programming Guide) | Microsoft Docs[^]
How to: Safely Cast by Using as and is Operators (C# Programming Guide) | Microsoft Docs[^]
 
Share this answer
 
Comments
The_Unknown_Member 9-Apr-18 7:07am    
I meant that it won't work because List of T doesn't support covariance (classes can't support covariance + it will break the type safety in this case). The question is mostly about the second part

IList<derived> derived = new List<derived>();
IList <base /> basee = derived;


Specifically this line:
IList <base /> basee = derived;

Here I am allowed to cast the derived to IList<base /> (of course it will fail in runtime but here i'm talking about compile time). How did the compiler determine that
the derived list can be casted to IList? Does it care about the generic parameters? Or it just cares about the inheritance tree of List<t> so in this case IList<t> is implemented by List<t> hence the compiler allows me to cast my list to IList without caring about the generics. Is this the case?
Maciej Los 9-Apr-18 7:13am    
IList is not a class. It's an interface. It makes the difference!
The_Unknown_Member 9-Apr-18 8:27am    
@Maciej Los Yes I know this.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900