给出以下课程:
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[])"
尝试访问方法"SomeBuilder'1<<>f__AnonymousType0'1<System.Int32>>.Build(int)"
失败。
任何帮助将不胜感激,thx。
不过,如果您对SomeDynamicHelper感兴趣,请参阅:http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invoker
EDIT1:
我在主要电话中做了这样的电话:
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在同一个程序集中声明匿名类型。但是,如果我们不能做声明,我们该怎么办?
好的,你可以用最后一个参数(skipVisibility)调用DynamicMethod(),设置为true!
希望这可以帮助其他人解决同样的问题:)
答案 0 :(得分:0)
您可以尝试在定义匿名类型的同一项目中使用[assembly: InternalsVisibleTo("Anonymously Hosted DynamicMethods Assembly")]
。
答案 1 :(得分:0)
“method”SomeDynamicHelper。(System.Object,System.Objec [])“尝试访问方法”SomeBuilder'1&lt;&lt;&gt; f__AnonymousType0'1&gt; .Build(int)“
从这里你可以看到动态方法试图运行一个名为Build的内部\ private方法,因为你得到MethodAccessException。
(匿名类型保存在新生成的类中)
添加InternalVisibleTo
并不总是有帮助,因为只有当你可以重写匿名类型程序集(手动或拦截)并且只有类型和方法是内部而不是私有时才有帮助。
在动态方法中,您可以将方法绑定到类型\ module,并跳过可见性检查,但这有助于访问指定模块的私有成员,因此,如果您尝试访问的类型位于不同的程序集中,则type \ method是私有的,你什么也做不了。
差不多。您向程序集注入了一个“秘密”属性,称为IgnoreAccessChecksTo
,然后除了有界模块和跳过可见性之外,它可能会起作用。
答案 2 :(得分:0)
我在使用IKVM转换的Guice注入的C#类中遇到了类似的错误。修复只是让受影响的类(在这种情况下可能是SomeBuilder
)公开,一切正常。