Reputation: 4776
I have the next classes:
public class EntityBase<T>
{
public T Id { get; set; }
}
And it's implementers:
public class ClassA : EntityBase<Int32>
{
...
}
public class ClassB : EntityBase<Int64>
{
...
}
And in the code, which dont know about classes - ClassA
and ClassB
it knows only about existance of the EntityBase<...>, I do something like this:
// Here for sure I get the list of `ClassA`
object obj = GetSomeHowListOfClassA();
List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;
And I get the error:
Unable to cast object of type 'System.Collections.Generic.List`1[...ClassA]' to type 'System.Collections.Generic.List`1[...EntityBase`1[System.Int32]]'.
I fix it like this:
var listOfEntityBases = new List<EntityBase<Int32>>(obj);
But I dont like this way, because I'm creating new List<>. Is there way to cast it? Thx for any advance.
Upvotes: 2
Views: 129
Reputation: 7514
You can not do it for clear reason. Let's assume this line of code will work:
List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;
This means that after that line you can do say following
listOfEntityBases.Add(new EntityBase<Int32>());
but actually this line in the same time will add EntityBase<Int32>
object to your obj
of type List<ClassA>
- which is definitely InvalidCast.
So, you just cannot declare the same variable as List<ClassA>
and List<EntityBase<Int32>>
in the same time.
Though, it is easily allowed for IEnumerable<T>
as you can not add new values for such collection.
And that's why they have in
and out
in generics declaration.
Upvotes: 2
Reputation: 37780
You can't do cast this way, because:
IList<T>
and ICollection<T>
aren't covariant.The only option you can do here (except making a copy of a list) is a casting to IEnumerabe<T>
:
var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;
Upvotes: 0