0

現時点で変数を取る関数がありTypeます。この関数はそれをリストに貼り付け、最終的にそのタイプのクラスを作成する必要があります。

今、私はそれを行います

object o=MyType.GetConstructors()[0].Invoke(new object[0]);

これはかなりハックであり、リフレクションのために中程度の信頼では機能しません(私は思う)。リフレクションなしでこれを行うより良い方法はありますか?

Type は、関数の一部としてこのように定義されます。クラスが必要でない場合はアプリケーションで作成されない可能性があるため、クラスを「遅延」して作成する必要があります。たとえば、次のように使用します

AddToList(typeof(Whatever)); 

関数呼び出しの変更に関する提案を受け付けています。オブジェクトを遅延して作成し、タイプを保存する(またはタイプのオブジェクトを作成する)必要があるだけです。

ラムダを検討しましたが、ここで機能するかどうかはわかりません。

4

3 に答える 3

3

ジェネリックの使用:

public void Method<T>() where T : class, new()
{
  //code
  T t = new T();
}

使用Activator(まだ反射、まあ):

object t = Activator.CreateInstance(yourTypeVariable);

個人的には、強く型付けされているため、最初のソリューションを好みます。ただし、どちらの方法でもパラメーターなしのコンストラクターしか使用できないことに注意してください。パラメータを渡す必要がある場合は、リフレクションまたは式ツリーが必要になります。

于 2011-01-14T02:10:23.297 に答える
2

別の代替ソリューションはFormatterServicesです。

object instance = FormatterServices.GetUninitializedObject(typeof(MyClass));

フィールド/プロパティを初期化せずにインスタンスが作成されることに注意してください。

class MyClass
{
   public int i = 99;
   public Object o = new object();
}

instance.i0 にinstance.oなり、null になります。純粋な非反射ソリューションを提供することは非常に困難です (常に を呼び出す必要があるためo.GetType())。このソリューションでは、基本的にオブジェクトをシリアル化してからオブジェクトに逆シリアル化するため、リフレクションを使用してそのコンストラクターを呼び出す必要はありません。ただし、シリアル化/逆シリアル化の際にはまだリフレクションがあります。

于 2011-01-14T02:19:28.730 に答える
0

ラムダについてさらに調査した結果、ラムダがはるかにエレガントなソリューションを提供し、リフレクションを使用しないことを発見しました

だから私は私のリスト定義で使用しました

public delegate MyBaseType TypeCreator();

...
public TypeCreator Creator;

そして私の関数呼び出しでは、シンプルでエレガントなラムダ:

AddToList(()=>{return new MyType();});

これは、パラメーターをコンストラクターに入れることができるため、私のリフレクション メソッドよりもかなりきれいだと思います。また、この質問の範囲外の他のいくつかの理由もあります。(それは私のプロジェクトによく合います)

于 2011-01-14T02:37:04.380 に答える