2012-09-17 13 views
7

Ho alcune classi come questo:Casting generico per tipo di interfaccia - Impossibile eseguire il cast oggetto di tipo 'System.RuntimeType' di digitare

public class Customer 
{ } 

public interface IRepository 
{ } 

public class Repository<T> : IRepository 
{ } 

public class CustomerRepository<Customer> 
{ } 

Poi, come da the answer to this question posso utilizzare la reflection per ottenere un elenco di i tipi a cui fa riferimento generici per ciascuno dei miei * Repository:

Quello che voglio è finire con un Dictionary<Type, IRepository>

Finora, ho questo:

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); 

Tuttavia, non gli piace il mio cast (IRepository)x
ottengo il seguente errore:

Unable to cast object of type 'System.RuntimeType' to type 'My.Namespace.IRepository'.

+2

Come stai * aspettandosi * di ottenere un'istanza quando hai solo un 'Tipo'? –

risposta

8

Non si può lanci (IRepository) type con il tipo è Type classe,

è possibile utilizzare Activator.CreateInstance per creare l'oggetto CustomerRepository, non è inoltre necessario utilizzare Select, utilizzare invece ToDictionary direttamente, il codice di seguito:

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); 
2

Se è un oggetto System.Type, come se x sia typeof(Repository<>), non è possibile eseguire il cast in questo modo. Il Type non è un'istanza.

Se x non avevano "liberi" parametri di tipo, cioè se x dove non generico o chiusi generica, quindi (IRepository)Activator.CreateInstance(x) potrebbe crearti un oggetto di tipo x. Ma non sono sicuro che sia ciò di cui hai bisogno. Ci sarà un costruttore di istanze senza parametri?

Problemi correlati