2011-10-27 106 views
1

DynamicMethods允許您爲您創建的委託指定目標實例。但是,看起來這在您使用結構類型時不起作用。它會失敗並告訴我它不能綁定到這個方法。是因爲我的IL沒有解開目標實例的錯誤?爲什麼我不能將DynamicMethod綁定到結構實例?

如果我在這裏改變A到一個類沒有問題。我究竟做錯了什麼? (也請不要建議致電Delegate.CreateDelegate綁定到GetType方法與目標實例)

下面是一個簡單的攝製:

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() 
); 

注:我使用的是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,這也適用於這裏:

如果方法是靜態的(在Visual Basic中的Shared)和它的第一個參數 是Object類型或值類型,那麼firstArgument能值爲 類型。在這種情況下,firstArgument會自動裝箱。自動 拳擊不會發生任何其他參數,因爲它會在C#或 Visual Basic函數調用。

的含義是第一個參數,以動態方式將需要object型的,並且你需要做的約束調用之前做了ldarg_0後跟拆箱。

相關問題