Casting generic to interface type - Unable to cast object of type 'System.RuntimeType' to type
Solution 1
You cannot cast (IRepository) type
with type is Type
class,
you can use Activator.CreateInstance
to create object CustomerRepository
, you also don't need to use Select
, instead, use ToDictionary
directly, the code below:
var myRepositories = Assembly.GetAssembly(typeof(Repository<>))
.GetTypes()
.Where(x => x.BaseType != null &&
x.BaseType.GetGenericArguments().FirstOrDefault() != null)
.ToDictionary(x => x.BaseType.GetGenericArguments().FirstOrDefault(),
x => Activator.CreateInstance(x) as IRepository );
Solution 2
If x
is a System.Type
object, like if x
is typeof(Repository<>)
, you can't just cast it like that. The Type
is not an instantiation.
If x
had no "free" type parameters, that is if x
where non-generic or closed generic, then (IRepository)Activator.CreateInstance(x)
might create you an object of type x
. But I'm not sure that's what you need. Will there be a parameterless instance constructor?
Related videos on Youtube
Alex
I'm a .net developer from Camberley, Surrey. Strong interest in web applications - emphasis on back end APIs. Recently working in serverless applications. Enjoy speaking at tech events where possible.
Updated on October 19, 2022Comments
-
Alex over 1 year
I have some classes like this:
public class Customer { } public interface IRepository { } public class Repository<T> : IRepository { } public class CustomerRepository<Customer> { }
Then, as per the answer to this question I can use reflection to get a list of types referenced by generics for each of my *Repository:
What I want to end up with is a
Dictionary<Type, IRepository>
So far, I have this:
Dictionary<Type, IRepository> myRepositories = Assembly.GetAssembly(typeof(Repository<>)) .GetTypes() .Where(typeof(IImporter).IsAssignableFrom) .Where(x => x.BaseType != null && x.BaseType.GetGenericArguments().FirstOrDefault() != null) .Select( x => new { Key = x.BaseType != null ? x.BaseType.GetGenericArguments().FirstOrDefault() : null, Type = (IRepository)x }) .ToDictionary(x => x.Key, x => x.Type);
However, it doesn't like my cast
(IRepository)x
I get the following error:Unable to cast object of type 'System.RuntimeType' to type 'My.Namespace.IRepository'.
-
Jon SkeetHow are you expecting it to get an instance when you've only got a
Type
?
-