2009-11-22 60 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