2012-09-17 28 views
7

我有一些類是這樣的:鑄造通用的接口類型 - 無法投型「System.RuntimeType」的對象鍵入

public class Customer 
{ } 

public interface IRepository 
{ } 

public class Repository<T> : IRepository 
{ } 

public class CustomerRepository<Customer> 
{ } 

然後,按照the answer to this question我可以使用反射來獲取列表通過仿製藥我的每一個*庫的引用類型:

我想直到結束是Dictionary<Type, IRepository>

到目前爲止,我有這樣的:

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

然而,它並不像我的演員(IRepository)x
我收到以下錯誤:

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

+2

當你只有一個'Type'時,你期待*它得到一個實例嗎? –

回答

8

你不能施放(IRepository) type與類型爲Type類,

可以使用Activator.CreateInstance創建對象CustomerRepository,您也不需要使用Select,而是直接使用ToDictionary,代碼如下:

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

如果xSystem.Type對象,就像xtypeof(Repository<>)一樣,您不能只是像這樣施放它。 Type不是一個實例。

如果x沒有「免費」的類型參數,即如果x其中非通用或關閉通用,然後(IRepository)Activator.CreateInstance(x)可能會造成您x類型的對象。但我不確定那是你需要的。會有一個無參數的實例構造函數嗎?

相關問題