実行時にクラスの名前を知っているという事実に基づいて、クラスのインスタンスを作成する方法はありますか。基本的に、文字列にクラスの名前があります。
Activator.CreateInstance メソッドを見てください。
とても簡単です。クラス名が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);
私はこのメソッドを正常に使用しました:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
返されたオブジェクトを目的のオブジェクトタイプにキャストする必要があります。
おそらく私の質問はもっと具体的だったはずです。私は実際に文字列の基本クラスを知っているので、それを解決しました:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Activator.CreateInstanceクラスには、同じことを異なる方法で実現するためのさまざまなメソッドがあります。オブジェクトにキャストすることもできますが、上記は私の状況に最も役立ちます。
私はゲームに遅れていることを知っています...しかし、あなたが探している解決策は、上記の組み合わせであり、インターフェースを使用してオブジェクトを公開アクセス可能な側面を定義することです。
次に、この方法で生成されるすべてのクラスがそのインターフェイスを実装する場合、インターフェイスタイプとしてキャストし、結果のオブジェクトを操作できます。
たとえば、データベースフィールド(文字列として格納)にさまざまな型の値を格納し、型名(つまり、String、bool、int、MyClass)の別のフィールドがある場合、そのフィールドデータから、おそらく、上記のコードを使用して任意のタイプのクラスを作成し、最初のフィールドの値を入力します。これはもちろん、文字列を正しい型に解析するメソッドを持っている保存している型に依存します。これを何度も使用して、ユーザー設定をデータベースに保存しました。
実装したい解決策について説明したようですが、解決しようとしている問題については説明していません。
おそらく、あなたは拡張性を備えた何かをしようとしているでしょう。その場合、 Managed Extensibility Framework をチェックすることをお勧めします。
ソリューション内の別のプロジェクトからクラスのインスタンスを作成するには、任意のクラスの名前(BaseEntityなど)で示されるアセンブリを取得し、新しいインスタンスを作成できます。
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");