抽象クラスがあり、それを拡張するクラスに初期化したい。
文字列として子クラス名があります。
これに加えて...
String childClassString;
MyAbstractClass myObject;
if (childClassString = "myExtenedObjectA")
myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
myObject = new ExtenedObjectB();
これどうやってするの?基本的に、ここでifステートメントを削除するにはどうすればよいですか?
Activator.CreateInstance()を見てください。
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
または
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
私はこれがうまくいくと信じています:
myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
最初のパラメータのnull
は、デフォルトで現在実行中のアセンブリになります。詳細なリファレンス: [〜#〜] msdn [〜#〜]
編集:MyAbstractClass
へのキャストを忘れました
別のアセンブリからオブジェクトをインスタンス化しようとしていたので、ここでいくつかの答えを実装するのに多少の困難がありました(同じソリューション内)。だから、私は自分が見つけたものを投稿すると思った。
まず、_Activator.CreateInstance
_メソッドにはいくつかのオーバーロードがあります。 Activator.CreateInstance(Type.GetType("MyObj"))
を呼び出すだけの場合、オブジェクトは現在のアセンブリで定義されていると想定し、MyObj
を返します。
Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
の回答で推奨されているように呼び出すと、代わりにObjectHandle
を返します。オブジェクトを取得するには、Unwrap()
を呼び出す必要があります。このオーバーロードは、別のアセンブリで定義されたメソッドを呼び出そうとするときに役立ちます(ところで、現在のアセンブリでこのオーバーロードを使用できますが、AssemblyName
パラメーターはnullのままにしてください)。
さて、AssemblyName
にtypeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
を使用するという上記の提案は実際にエラーを引き起こし、それを機能させることができなかったことがわかりました。 _System.IO.FileLoadException
_を取得します(ファイルまたはアセンブリをロードできませんでした...)。
私が仕事に就いたのは次のとおりです。
_var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();
_