2012-01-23 75 views
11

所以我有一個通用類,它可能需要在它的一個方法內部自己創建一個不同類型的通用實例,該類型通過重新獲得。c#在運行時創建一個未知的通用類型

這很重要,因爲這個知識庫將T映射到數據庫表[它是我正在寫的ORMish],如果表示T的類具有代表另一個表的集合,我需要能夠實例並將它傳遞給知識庫[ala Inception]。
我提供的方法,以防萬一它更容易看到問題。

private PropertiesAttributesAndRelatedClasses GetPropertyAndAttributesCollection() 
     { 
    // Returns a List of PropertyAndAttributes 
    var type = typeof(T); 
//For type T return an array of PropertyInfo 

    PropertiesAttributesAndRelatedClasses PAA = new PropertiesAttributesAndRelatedClasses(); 
//Get our container ready 

     PropertyAndAttributes _paa; 
     foreach (PropertyInfo Property in type.GetProperties()) 
//Let's loop through all the properties. 

      {      
     _paa = new PropertyAndAttributes(); 
//Create a new instance each time. 

     _paa.AddProperty(Property); 
//Adds the property and generates an internal collection of attributes for it too 

     bool MapPropertyAndAttribute = true; 
     if (Property.PropertyType.Namespace == "System.Collections.Generic") 
    //This is a class we need to map to another table 
       { 
        PAA.AddRelatedClass(Property); 
       //var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString()); 
        } 
        else 
        { 
         foreach (var attr in _paa.Attrs) 
         { 
          if (attr is IgnoreProperty) 
//If we find this attribute it is an override and we ignore this property. 
          { 
           MapPropertyAndAttribute = false; 
           break; 
          } 
         } 
        } 
        if (MapPropertyAndAttribute) 
         PAA.AddPaa(_paa); 
      //Add this to the list. 
       } 
       return PAA; 
      } 

所以給出 GenericRepository,我想打一個GenericRepository我會怎麼做呢? 我需要一些作品來替代該生產線是

//     var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString()); 
+0

是怎樣的屬性(類型的一個'系統.Collections.Generic')在你的C#代碼中聲明?它的類型參數''與擁有該屬性的'GenericRepository '相同嗎? – dasblinkenlight

+0

不,基本上它只是另一個類的泛型集合,作爲一個類的屬性。 即一個教師類有一個類的類列表。 版本庫獲取教師類,並且還必須處理類類,但是由於它確實獲取了T,因此必須找出它使用反射必須處理的內容。 – Jordan

+0

因此,將'Teacher'類中的屬性聲明爲List 類{/ * getter和/或setter * /}'?那麼'Activator.CreateInstance(Property.GetType())'工作嗎? – dasblinkenlight

回答

28

我認爲你正在尋找的MakeGenericType方法:

// Assuming that Property.PropertyType is something like List<T> 
Type elementType = Property.PropertyType.GetGenericArguments()[0]; 
Type repositoryType = typeof(GenericRepository<>).MakeGenericType(elementType); 
var repository = Activator.CreateInstance(repositoryType); 
+0

如果我可以,我遇到了1個問題。我無法訪問給定存儲庫的任何方法。 ((GenericRepository )存儲庫).GetAll() 這適當地工作,我怎麼能在它正確的工作,它在我看到的通用存儲庫和我做 ?代碼,這樣我不需要這個?顯然,我只能在即時窗口中進行操作,因爲我知道它代表的類型。 – Jordan

+0

@Jordan,你可以用'GetAll'方法創建一個非泛型'IRepository'接口,該方法返回一個對象數組,並在'GenericRepository '類中明確地實現這個接口。或者你可以使用反射來動態調用該方法,但速度較慢... –

+0

阿好。另外我意識到如果我聲明它是動態的而不是var,它可以工作 – Jordan

4
Activator.CreateInstance(typeof(GenericRepository<>).MakeGenericType(new Type[] { Property.GetTYpe() })) 
+1

這將創建'GenericRepository '的實例,因爲'Property .GetType()'返回'RuntimePropertyInfo' ... –

相關問題