动态方法和MethodAccessException
本文关键字:MethodAccessException 方法 动态 | 更新日期: 2023-09-27 18:18:41
给出以下类:
class SomeBuilder<T>
{
public static object Build(int index)
{
...
}
}
class SomeHelper
{
public object GetBuildObj(object value)
{
var valuetype = value.GetType();
var methodinfo = typeof(SomeBuilder<>).MakeGenericType(valuetype).GetMethod("Build");
var handler = SomeDynamicHelper.GetMethodInvoker(methodinfo);
var result = hander(null, new object[]{1});
}
}
SomeBuilder是一个泛型类型,所以我需要调用MakeGenericType()来使事情正确。
当我传递一个普通类型,如'class person'作为值时,一切正常,这很好。
,但当我传递一个匿名类型,如:new {id=1},处理程序被成功创建。但是调用这个动态处理程序,我得到了一个MethodAccessException与这些消息:
"method "SomeDynamicHelper.(System.Object, System.Objec[])"
try access method "SomeBuilder'1<<>f__AnonymousType0'1<System.Int32>>.Build(int)"
failed.
任何帮助将不胜感激,谢谢。
如果您对SomeDynamicHelper感兴趣,请参阅:
http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invokeredit1:
我在main中这样做了调用:
static void Main(string[] args)
{
// pass a normal class, this will be fine
var value = new Person { id = 1};
new SomeHelper().GetBuildObj(value);
// pass a anonymous type
var value = new { id = 1};
new SomeHelper().GetBuildObj(value); // oops, got a exception here!
}
edit2:
基于注释,我改变了我的代码:
class SomeHelper
{
public object GetBuildObj(object value)
{
//this time i do not use the value, but create a new inner value:
var valuenew = new { id = 1 };
var valuetype = valuenew.GetType();
var methodinfo = typeof(SomeBuilder<>).MakeGenericType(valuetype).GetMethod("Build");
var handler = SomeDynamicHelper.GetMethodInvoker(methodinfo);
var result = hander(null, new object[]{1});
}
}
嗯,这次也不例外,但是……不幸的是,出现了一个新问题……也许我应该为新的问题开一个新的帖子。
谢谢大家的关注。
edit3:
嗨,经过一番挖掘,我也发现了一些有用的信息。例如,SomeDynamicHelper.GetMethodInvoker()代码如下:DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
这是我们在这里用来动态创建方法的核心。对于我们的上下文,我们需要在与SomeHelper和SomeBuilder相同的程序集中声明匿名类型。但是,如果我们不能报关,我们该怎么办呢?
好的,你可以调用DynamicMethod()最后一个参数(skipVisibility),设置为true!
希望这将帮助其他人有同样的问题:)
"方法" SomeDynamicHelper。(系统。对象,system . Object[])"尝试访问方法"SomeBuilder'1<<>f__AnonymousType0'1>.Build(int)"
从这里你可以看到,动态方法试图运行一个名为Build的内部私有方法,为此你得到了MethodAccessException。
(匿名类型保存在新生成的类中)
添加InternalVisibleTo
并不总是有帮助,因为只有当你可以重写匿名类型汇编(手动或拦截),只有当类型和方法是内部的,而不是私有的,它才有帮助。
在动态方法中,你可以将方法绑定到类型'module,并跳过可见性检查,但这有助于访问指定模块的私有成员,所以如果你试图访问的类型是在不同的程序集中,而类型'method是私有的,你不能做任何事情。
几乎。有一个"秘密"属性,您注入到您的程序集,称为IgnoreAccessChecksTo
,然后除了有界模块和跳过可见性也许它会起作用。
您可以尝试在定义匿名类型的同一项目中使用[assembly: InternalsVisibleTo("Anonymously Hosted DynamicMethods Assembly")]
我在尝试使用ikvm转换的Guice注入c#类时遇到了类似的错误。修复的方法是将受影响的类(在本例中可能是SomeBuilder
)公开,然后一切正常工作。