web-dev-qa-db-ja.com

C#動的文字列を既存のクラスに変換する

Windowsアプリ内で、C#を使用して、レポートを作成するためにクラスに依存するレポートモジュールがあります。ただし、多くのレポートがあり、それぞれについてコーディングする必要はありません。

フローは次のようになります。レポートエディタ内で、レポートには文字列としてクラス(つまり、「アプリケーション」)が割り当てられます。ユーザーが実行するレポートを選択すると、コードはSQLクエリからデータを取得します。コードはデータを取得し、データを配置するクラスを見つけます。次に、レポートはクラスを取得し、クラスからのデータをレポートに入力します。

これが私のジレンマです。コードが割り当てられたクラスを適切なクラスオブジェクトに変換するように、コードを動的にするにはどうすればよいですか?

念頭に置いて例:

gVar = Report;
(gVar.ReportClass)oClass = new gVar.ReportClass;
11
mattgcon

Type.GetType (具体的には、stringパラメーターを受け取るオーバーロードの1つ(たとえば、 Type.GetType(string) ))を使用して、適切なクラスのTypeのインスタンスをロードします。次に、Typeのインスタンスで Activator.CreateInstance または Type.GetConstructor を使用して、インスタンスをインスタンス化します。

だから、

Type type = Type.GetType(assemblyQualifiedName);
object instance = Activator.CreateInstance(type);

タイプがmscorlibまたは現在実行中のアセンブリにない限り、 アセンブリ修飾名 を渡す必要があることに注意してください。

さらに、Activator.CreateInstanceは、デフォルトのコンストラクターの存在を前提としています。デフォルトのコンストラクターがない場合、またはコンストラクターにいくつかのパラメーターを渡す必要がある場合は、コンストラクターパラメーターを指定できるActivator.CreateInstanceoverload を使用するか、適切なコンストラクターをロードするためにType.GetConstructorを使用する必要があります。 。

9
jason

リフレクションを使用してそれを行うことができます。それらすべてに同様の基本クラスまたはインターフェースを与えると、次のようなことができます。

myBaseReport report = (myBaseReport)System.Activator.CreateInstance("MyAssemblyName", myClassStringWithFullNameSpace).Unwrap();

これは、という名前のアセンブリに入り、クラスを直接ロードします。クラス文字列は問題の型のフルネームであるため、MyGlobalNamespace.MyCustomNameSpace.MySpecificTypeのようになります。これにより、特定のタイプのレポートを作成し、それを基本クラスタイプまたはインターフェイスタイプに入れることができます。

4
Joel Etherton

暗黙の演算子を使用しても問題ありません。

それはあなたが次のようなことをすることを可能にするので、それはあなたのニーズに良いように聞こえます:

Orange orange = new Orange();
Apple apple = (Apple)orange;

または:

string appleJson = "{ Weight: '2kg' }";
Apple apple = appleJson;

暗黙の演算子は、そのApple-JSONでシリアル化された文字列を通常のAppleタイプのオブジェクトに逆シリアル化します。

これがあなたが探しているものであるかどうかはわかりません。これが利用可能なC#機能である場合、誰も投票しないことを願っています。

編集:私は質問を誤解しました。私が間違っていたので、私の答えに反対票を投じたコメント投稿者に感謝します。

編集2:

他のアクティベーター/リフレクションアプローチ(現在の質問の作成者にとって正しいと思われる)を採用し、「取得したレポートインスタンスのプロパティを埋める方法」に関する他の質問を読んで、いくつかの解決策を提案したいと思います。

プロパティのない「ReportPropertyAttribute」のような属性、デフォルトコンストラクターを定義し、提案された属性でマークされたプロパティをリフレクションで検査できます。

または、構成ファイルまたは構成セクション(通常の.NET構成API)を定義して、「既知のレポートタイプ」および「どのプロパティが特定のレポートタイプの引数またはパラメーターであるか」を定義できます。

これがあなたのニーズに合っていることを願っています!

2

ここで何を求めているのか、正確には少しわかりません。しかし、私が読んでいることに基づいて、型名を含む文字列があり、それに基づいてクラスをインスタンス化したいですか?リフレクションを使用してこれを行うことができます...

Type type = Type.GetType(strTypeName);
object oClass = Activator.CreateInstance(type);
2
Steve Danner