2012-04-03 8 views
1

私はActivator.CreateInstance()objectの新しいインスタンスを作成できることを知っています。しかし、私はILExpressionでインスタンスを作成する方法を探しています。私は、型のインスタンスを作成するための動的ラムダを作成し、ラムダをキャッシュしてオブジェクトの初期化を高速化できると思います。私は正しい?私を助けてくれますか?ダイナミックラムダとILでオブジェクトの新しいインスタンスを作成する方法は?

+0

重複http://stackoverflow.com/questions/9788813/best-way-実行時に決定されるタイプのインスタンス作成/ 9789971#9789971 –

答えて

4

Expression.New()を使用してオブジェクトの作成を表すことができます。パラメータのないコンストラクタを持つType、またはコンストラクタパラメータを表すExpressionと一緒にConstructorInfoを渡すことができます。 objectを返したい場合は、値タイプに対しても機能させたい場合は、Expression.Convert()も追加する必要があります。一緒にすべてを置く

Activator.CreateInstance()と同等のは次のようになります。

object CreateInstance(Type type) 
{ 
    return Expression.Lambda<Func<object>>(
     Expression.Convert(Expression.New(type), typeof(object))) 
     .Compile()(); 
} 

あなたはILで同じことをしたい場合は、参照型のためthe newobj instructionを使用する必要があります。あなたが値タイプに対して同じことを行いたい場合、あなたはそれを、その型のローカル変数を作成し、それをボックスと返すことができます。

object CreateInstance(Type type) 
{ 
    var method = new DynamicMethod("", typeof(object), Type.EmptyTypes); 
    var il = method.GetILGenerator(); 

    if (type.IsValueType) 
    { 
     var local = il.DeclareLocal(type); 
     // method.InitLocals == true, so we don't have to use initobj here 
     il.Emit(OpCodes.Ldloc, local); 
     il.Emit(OpCodes.Box, type); 
     il.Emit(OpCodes.Ret); 
    } 
    else 
    { 
     var ctor = type.GetConstructor(Type.EmptyTypes); 
     il.Emit(OpCodes.Newobj, ctor); 
     il.Emit(OpCodes.Ret); 
    } 

    return method.Invoke(null, null); 
} 
+0

ありがとう、私はそれを理解しています。したがって、コントラクタにいくつかの議論がある場合、どのようにテーマを提供できますか?もう1つのQは、「表現」についてはどこで知ることができるのですか?どこでそれを学びましたか?事前にお礼します –

+0

さまざまな.Netタイプについて知る必要があるものは[MSDN](http://msdn.microsoft.com/en-us/library/gg145045.aspx)([式]のドキュメントを含む) (http://msdn.microsoft.com/en-us/library/bb356138.aspx)。そして私が言ったように、おそらく 'Expression.Constant()'を使って 'New()'メソッドへのパラメータとしてコンストラクタにパラメータを渡すことができます。 – svick

関連する問題