C# 反射方法访问异常
我在Silverlight中有一个简单的代码:C# 反射方法访问异常,c#,silverlight,reflection,C#,Silverlight,Reflection,我在Silverlight中有一个简单的代码: public void temp() { try { WriteableBitmap obj = new WriteableBitmap(10, 10); //PropertyInfo pr = obb.GetType().GetProperty("Pixels"); Type type = obj.GetType(); Type ty
public void temp()
{
try
{
WriteableBitmap obj = new WriteableBitmap(10, 10);
//PropertyInfo pr = obb.GetType().GetProperty("Pixels");
Type type = obj.GetType();
Type typeofType = type.GetType();
MethodInfo getPropMethod = typeofType.GetMethod("GetProperty", new Type[] { typeof(string) }); //get method info
PropertyInfo pix1 = type.GetProperty("Pixels"); // first call - no exceptions
PropertyInfo pix2 = (PropertyInfo)getPropMethod.Invoke(type, new object[] { "Pixels" }); // second call - MethodAccessException
}
catch (Exception ex)
{
}
}
方法GetProperty的第一次调用已成功执行,并且未引发异常。
但是第二个调用methodInfo.Invoke抛出MethodAccessException——为什么会发生这种情况
异常和堆栈跟踪:
MethodAccessException: Attempt by security transparent method 'System.Type.GetProperty(System.String)' to access security critical method 'SilverlightApplication3.MainPage.temp()' failed.
in System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
in System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
in System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
in SilverlightApplication3.MainPage.temp()
Silverlight中的反射仅限于编译时可用的内容,可能是在第一次调用函数时,条件得到满足,在第一次调用之后,某些内容发生了变化,反射无法执行 在Silverlight中,不能使用反射来访问私有类型和 成员。如果类型或成员的访问级别会阻止您 通过在静态编译代码中访问它,您无法访问它 动态地使用反射
请参阅文档我认为这是Silverlight/CoreCLR模型中强大安全限制的结果 我认为反射方法(或其底层实现)将被视为
SecurityCritical
。您现在使用的反射代码似乎仍然满足这一点,但我相信这是一个特别不允许的情况(可能是出于安全考虑)。使用委托和编译时引用的类似代码在Silverlight中运行良好,包括调用该委托的各种方式:
var getPropMethodDelegate = new Func<string, PropertyInfo>(obj.GetType().GetType().GetProperty);
getPropMethodDelegate("Pixels");
getPropMethodDelegate.Invoke("Pixels");
getPropMethodDelegate.DynamicInvoke("Pixels");
或者在这一点上,更直接地做:
if (reflectionType == "GetProperty")
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);
}
你可以做更多的工作来简化这个过程(例如,将例程放在字典中以便快速查找),但是对于Silverlight/CoreCLR上下文,我不知道如何解决这个问题。对于两个调用,你的输入是否总是相同的
新对象[]{“像素”}
?我必须在工作时仔细检查。LinqPad中的快速测试工作正常,所以如果Silverlight的反射层中有额外的安全检查来防止这种情况发生,或者只是在其可用API中进行了一些小调整,我也不会感到惊讶。你能发布完整的异常消息和堆栈跟踪吗?堆栈太长,无法放入注释,请参见图片不要在注释中添加问题相关信息,请编辑你的问题并更新其内容。Chris Sinclair-是的,你说得对,代码在控制台应用程序中运行良好,但是Silverlight中没有。我添加第一个调用是为了证明函数GetProperty
在静态编译的代码中可用,如果我删除这个调用-没有任何更改。Silverlight中似乎还有其他限制或bug。@AlexScherbinin第一次调用没有演示任何此类内容。安全性限制适用于通过反射调用方法,直到第二次调用时才真正尝试反射。
if (reflectionType == "GetProperty")
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);
}