2009-11-22 72 views
8

我想從動態生成的內部方法調用。 il代碼很簡單:ldarg_0,callvirt,ret。是否可以從.NET中的動態方法調用內部方法?

執行該方法失敗,TypeLoadException說它無法加載定義內部方法的類型。

當我想到它時,這似乎是合乎邏輯的,因爲動態方法主機程序集不是方法聲明類型程序集的朋友。

但是,我期望動態方法仍然能夠工作,就像Delegate.CreateDelegate的工作。畢竟,我設法得到了內部方法的MethodInfo,所以權限的障礙在我身後。

無論如何,問題是「是否可以從動態生成的內部方法調用?」

謝謝。

編輯:

下面是一個簡單的代碼示例演示問題:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Reflection.Emit; 

namespace A 
{ 
    internal class Data 
    { 
    internal string String { get; set; } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     Expression<Func<Data, string>> expr = x => x.String; 
     var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true); 
     var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo); 
     var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }); 
     var gen = dm.GetILGenerator(); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Castclass, typeof(Data)); 
     gen.Emit(OpCodes.Callvirt, getterInfo); 
     gen.Emit(OpCodes.Ret); 
     var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); 

     var data = new Data() { String = "Hello" }; 
     var str1 = getter1(data); 
     var str2 = getter2(data); 
    } 
    } 
} 

在代碼中,我創建了兩個打開實例代表訪問Data.String實例屬性:

  • 使用Delegate.CreateDelegate類型安全的getter1
  • uns uns使用DynamicMethod的afe getter2

由Delegate.CreateDelegate創建的類型安全委託的工作方式,而使用DynamicMethod的類委託失敗,並帶有TypeLoadException。

請注意,我不希望採用類型安全方法,因爲創建getter的上下文不是通用的。當然,我可以解決這個問題,但問題是現在的問題 - 爲什麼DynamicMethod在Delegate.CreateDelegate成功的地方失敗?

+0

TypeLoadException意味着程序集無法找到 - fusion日誌查看器說什麼? – 2009-11-22 06:57:43

+0

融合日誌是空的。加載程序集應該沒有問題。所有相關的程序集都位於同一個文件夾中。 – mark 2009-11-22 07:37:24

+0

@JeremyMcGee是對的。在調試模式下獲取AppDomain中加載的程序集列表,並檢查目標程序集。另外,最好把你的代碼放在這裏來檢查。 – 2009-11-22 09:53:01

回答

6

如果您跳過可見性檢查,它將起作用。

改變這一行

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true); 

msdn:(尤其是表中的所有規則)

這是在構造函數中DOCO。

restrictedSkipVisibility類型: System.Boolean真跳過由動態 方法的MSIL訪問類型和成員 JIT 可視性檢查,與此限制:組件的 信任級別 包含這些類型和成員必須等於或小於發出 動態方法的調用堆棧的信任級別 ;否則,是錯誤的。

+0

DynamicMethod不在.net標準中,有什麼辦法可以在.net標準中做到這一點? – trampster 2017-03-11 04:29:43

相關問題