我正在尝试从动态生成的方法中调用内部方法。il 代码很简单:ldarg_0、callvirt、ret。
执行该方法失败,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
- 使用 DynamicMethod 输入不安全的 getter2
由 Delegate.CreateDelegate 创建的类型安全委托有效,而使用 DynamicMethod 的委托因 TypeLoadException 而失败。
请注意,我不希望采用类型安全的方法,因为创建 getter 的上下文不是通用的。当然,我可以解决这个问题,但现在的问题是委托人的问题 - 为什么 DynamicMethod 在 Delegate.CreateDelegate 成功的地方失败?