2010-02-11 99 views
48

我有一個抽象類,我想將它初始化爲一個擴展它的類。c#實例化字符串中的類

我有孩子類名字符串。

除此之外...

String childClassString; 
MyAbstractClass myObject; 

if (childClassString = "myExtenedObjectA") 
    myObject = new ExtenedObjectA(); 
if (childClassString = "myExtenedObjectB") 
    myObject = new ExtenedObjectB(); 

我怎樣才能做到這一點?基本上我怎麼擺脫這裏的if語句?

+1

爲什麼你需要一個字符串實例化類?根據你的情況,可能會有「更清潔」的解決方案,特別是如果你不願意使用反射。 – 2010-02-11 21:28:04

+1

@SylvestreEquy但是也許在別人的情況下,這只是解決方案...... SO上的問題不僅僅爲那些問他們的人提供服務。 – 2014-11-12 17:42:06

回答

90

看看Activator.CreateInstance()。

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName"); 

var type = Type.GetType("MyFullyQualifiedTypeName"); 
var myObject = (MyAbstractClass)Activator.CreateInstance(type); 
+6

工作就像一個魅力。如果任何人在獲取完全限定名稱時遇到問題,這段代碼是有用的'string typex = typeof(classname).AssemblyQualifiedName; – 2013-06-21 10:50:16

+0

儘管'typeName'參數的'GetType'文檔顯示「該類型的程序集限定名稱」,您實際上不需要包含程序集名稱。如果類型位於調用程序集中,則僅限名稱空間限定的類型名稱就足夠了。 – 2015-05-22 15:43:21

18

我認爲這應該工作:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString); 

在第一個參數默認爲當前執行的程序集的null。欲瞭解更多參考:MSDN

編輯:忘了投給MyAbstractClass

1

我不得不實施一些問題的答案在這裏,因爲我試圖從不同的組件實例化對象有些困難(但在相同的解決方案)。所以我想我會發布我發現的工作。

首先,Activator.CreateInstance方法有幾個重載。如果您只需撥打Activator.CreateInstance(Type.GetType("MyObj")),即假定該對象在當前程序集中定義,並返回MyObj

如果你把它作爲在這裏的答案推薦:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那麼它,而不是返回一個ObjectHandle,你需要調用它的Unwrap()讓你的對象。當嘗試調用另一個程序集中定義的方法時,此重載很有用(順便說一下,您可以在當前程序集中使用此重載,只需將參數AssemblyName保留爲空)。

現在,我發現上面的建議使用typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedNameAssemblyName實際上給了我錯誤,我無法讓它工作。我會得到System.IO.FileLoadException(無法加載文件或程序集...)。

我沒去工作如下:

var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject"); 
MyObject obj = (MyObject)container.Unwrap(); 
obj.DoStuff();