2012-06-22 141 views
1

我試圖完成一些看起來有些複雜的東西,但對我的情況會非常有幫助,看起來像這樣。實例化一個知道通用基類的泛型類型

public class CommonBaseClass {} 
    public class Type1Object : CommonBaseClass {} 
    public class Type2Object : CommonBaseClass {} 
    public class Type3Object : CommonBaseClass {} 

    public static Dictionary<string, Type> DataTypes = new Dictionary<string, Type>() 
    { 
     { "type1" , typeof(Type1Object) }, 
     { "type2" , typeof(Type2Object) }, 
     { "type3" , typeof(Type3Object) } 
    }; 

    public static CommonBaseClass GetGenericObject(string type) 
    { 
     return new DataTypes[type]();  //How to instantiate generic class? 
    } 

因爲我可以保證,所有構造函數都有我知道這將工作相同的簽名,只是不知道如何讓編譯器知道。

在此先感謝

+0

我想我可以只寫此作爲代表,仍然好奇,如果有一個更通用的方法 – jimmyjambles

回答

6

我沒有看到這裏的任何仿製藥真的,但它看起來像你想:

return (CommonBaseClass) Activator.CreateInstance(DataTypes[type]); 

如果需要使用參數的構造函數,使用Activator.CreateInstance替代超載。

另外,考慮改變你的字典是代表:

private static Dictionary<string, Func<CommonBaseClass>> DataTypes = 
    new Dictionary<string, Func<CommonBaseClass>> 
    { 
     { "type1",() => new Type1Object() } 
     { "type2",() => new Type2Object() }, 
     { "type3",() => new Type3Object() } 
    }; 

public static CommonBaseClass GetGenericObject(string type) 
{ 
    return DataTypes[type](); 
} 
+0

+1。請注意,根據性能目標,將'String'設置爲'Func '映射可能更好,以避免反射開銷。 –

+1

@AlexeiLevenkov:請參閱我在編輯您的評論時所做的修改:) –

+0

感謝您的幫助,代表詞典是完美的 – jimmyjambles

4

試試這個:

public class Foo 
{ 
    public static CommonBaseClass GetGenericObject<T>() where T : CommonBaseClass 
    { 
     return (CommonBaseClass)Activator.CreateInstance<T>(); 
    } 

    public void Test() 
    { 
     CommonBaseClass b = GetGenericObject<Type1Object>(); 
    } 
} 

使用泛型可以解決這個問題,有很多比有類型的映射的字典更好。

2

一個小的測試應用程序:

namespace ConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var dataTypes = new Dictionary<string, Type> 
      { 
       {"type1", typeof (Type1Object)}, 
       {"type2", typeof (Type2Object)}, 
       {"type3", typeof (Type3Object)} 
      }; 

      Func<string, CommonBaseClass> GetGenericObject = t => 
      { 
       return (CommonBaseClass)Activator.CreateInstance(dataTypes[t]); 
      }; 

      var myGenericObject = GetGenericObject("type1"); 
     } 
    } 

    public class CommonBaseClass { } 
    public class Type1Object : CommonBaseClass { } 
    public class Type2Object : CommonBaseClass { } 
    public class Type3Object : CommonBaseClass { } 
}