web-dev-qa-db-ja.com

文字列からクラスのインスタンスを作成します

実行時にクラスの名前を知っているという事実に基づいて、クラスのインスタンスを作成する方法はありますか。基本的に、文字列にクラスの名前があります。

193
PeteT

Activator.CreateInstance メソッドを見てください。

148
Matt Hamilton

とても簡単です。クラス名がCarで、名前空間がVehiclesであると仮定し、パラメーターをVehicles.Carとして渡します。これは、タイプCarのオブジェクトを返します。このように、クラスのインスタンスを動的に作成できます。

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}

完全修飾名 (つまり、この場合はVehicles.Car)が別のアセンブリにある場合、Type.GetTypeはnullになります。このような場合、すべてのアセンブリをループして、Typeを見つけます。そのためには、以下のコードを使用できます

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

ここで、パラメータ化されたコンストラクタを呼び出したい場合は、次のようにします

Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type

の代わりに

Activator.CreateInstance(t);
58
Sarath Avanavu

私はこのメソッドを正常に使用しました:

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)

返されたオブジェクトを目的のオブジェクトタイプにキャストする必要があります。

52
Ray Li

おそらく私の質問はもっと具体的だったはずです。私は実際に文字列の基本クラスを知っているので、それを解決しました:

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

Activator.CreateInstanceクラスには、同じことを異なる方法で実現するためのさまざまなメソッドがあります。オブジェクトにキャストすることもできますが、上記は私の状況に最も役立ちます。

20
PeteT

私はゲームに遅れていることを知っています...しかし、あなたが探している解決策は、上記の組み合わせであり、インターフェースを使用してオブジェクトを公開アクセス可能な側面を定義することです。

次に、この方法で生成されるすべてのクラスがそのインターフェイスを実装する場合、インターフェイスタイプとしてキャストし、結果のオブジェクトを操作できます。

4
Denny

たとえば、データベースフィールド(文字列として格納)にさまざまな型の値を格納し、型名(つまり、String、bool、int、MyClass)の別のフィールドがある場合、そのフィールドデータから、おそらく、上記のコードを使用して任意のタイプのクラスを作成し、最初のフィールドの値を入力します。これはもちろん、文字列を正しい型に解析するメソッドを持っている保存している型に依存します。これを何度も使用して、ユーザー設定をデータベースに保存しました。

3
Greg Osborne

実装したい解決策について説明したようですが、解決しようとしている問題については説明していません。

おそらく、あなたは拡張性を備えた何かをしようとしているでしょう。その場合、 Managed Extensibility Framework をチェックすることをお勧めします。

3
Jay Bazuzi

ソリューション内の別のプロジェクトからクラスのインスタンスを作成するには、任意のクラスの名前(BaseEntityなど)で示されるアセンブリを取得し、新しいインスタンスを作成できます。

  var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
2
asd