Home > Enterprise >  Casting object to Dictionary<Guid,AbstractBaseClass> without first casting to Dictionary<Gu
Casting object to Dictionary<Guid,AbstractBaseClass> without first casting to Dictionary<Gu

Time:07-13

If I have an abstract base class called MyBaseClass, and a class deriving from MyBaseClass called MyDerivedClass, is there a way to cast an object that I know is a Dictionary<Guid,MyDerivedClass> to a Dictionary<Guid,MyBaseClass> instead?

I get an invalid cast error when I do:

var dict = (Dictionary<Guid,MyBaseClass>)obj; // Where obj is "object" type but I know is a Dictionary<Guid,MyDerivedClass>. 
// This throws an invalid cast error.

The thing that has me confused is that casting an obj that I know is a List<MyDerivedClass> to a List<MyBaseClass> actually works. This works:

var list = (List<MyBaseClass>)obj; // Where obj is "object" type but I know is a List<MyDerivedClass>
// This works

Is there any way to cast an object that is Dictionary<Guid,MyDerivedClass> to Dictionary<Guid,MyBaseClass> without first casting to Dictionary<Guid,MyDerivedClass>? I'd like to avoid have to try casting each derived class if possible.

CodePudding user response:

.NET uses reified generics, so (unlike covariant/contravariant interfaces and arrays) you cannot cast generic classes to have a different signature from what the object actually is. Your example with a List actually doesn't behave the way you say it does:

object obj = new List<MyDerivedClass>();
var list = (List<MyBaseClass>)obj; // invalid cast exception

You can create a new dictionary, though.

var dict = ((Dictionary<Guid, MyDerivedClass>)obj)
    .ToDictionary(d => d.Key, d => (MyBaseClass)d.Value);

This will create a copy, and is more expensive than a cast, but for most use cases it won't significantly impact your application's performance.

You could technically create your own class that wraps a differently-typed dictionary and implements an interface like IDictionary<,>, so you could avoid the up-front cost of creating the dictionary but incur slightly more cost as you use the dictionary.

But, in summary, there is no way to simply cast a generic class to a type that it is not.

  • Related