2011-10-27 13 views
1

DynamicMethodでは、作成するデリゲートのターゲットインスタンスを指定できます。しかし、struct型を使用すると、これは機能しません。このメソッドにバインドできないという例外が発生して失敗します。私のイリノイは目標のインスタンスをアンボックスしないのでエラーですか?DynamicMethodをstructインスタンスにバインドできないのはなぜですか?

ここでAをクラスに変更すると、問題なく動作します。私は間違って何をしていますか?

struct A { } 
... //then some where in code:: 
Func<Type> f = CodeGen.CreateDelegate<Func<Type>>(il=> 
    il.ldarga_s(0) 
    .constrained(typeof(A)) 
    .callvirt(typeof(object).GetMethod("GetType")) 
    .ret(), 
    name:"Constrained", 
    target:new A() 
); 

注: (また、ターゲット・インスタンスにGetTypeメソッドにバインドするDelegate.CreateDelegateを呼び出すことをお勧めしないでください)

ここでは、サンプルREPROである私は、流れるようなインターフェイスのためEmittedライブラリを使用していますILのために。 CodeGenメソッドのコードもここにあります。

public static class CodeGen 
{ 
    public static TDelegate CreateDelegate<TDelegate>(Action<ILGenerator> genFunc, string name = "", object target = null, bool restrictedSkipVisibility = false) 
     where TDelegate:class 
    { 
     ArgumentValidator.AssertGenericIsDelegateType(() => typeof(TDelegate)); 
     ArgumentValidator.AssertIsNotNull(() => genFunc); 

     var invokeMethod = typeof(TDelegate).GetMethod("Invoke"); 
     var @params = invokeMethod.GetParameters(); 
     var paramTypes = new Type[@params.Length + 1]; 
     paramTypes[0] = target == null ? typeof(object) : target.GetType(); 
     @params.ConvertAll(p => p.ParameterType) 
      .CopyTo(paramTypes, 1); 
     var method = new DynamicMethod(name ?? string.Empty, invokeMethod.ReturnType, paramTypes, restrictedSkipVisibility); 
     genFunc(method.GetILGenerator()); 

     return method.CreateDelegate<TDelegate>(target); 
    } 
} 

答えて

0

もここに適用されhttp://msdn.microsoft.com/en-us/library/74x8f551.aspxで重要な注意事項、を参照してください:メソッドはstatic(Visual BasicではShared)であり、その最初のパラメータ がObject型またはValueTypeにである場合、firstArgument、

をすることができます値は となります。この場合、firstArgumentは自動的に囲まれます。自動 C#または Visual Basic関数呼び出しと同様に、他の引数でボクシングが発生しません。

含意はあなたの動的メソッドの最初の引数の型objectであることが必要になります、そしてあなたが制約された呼び出しを行う前にVHS版に続いてldarg_0を行う必要がありますということです。

関連する問題