反射方法访问异常
本文关键字:异常 访问 方法 反射 | 更新日期: 2023-09-27 18:34:44
我在Silverlight中有一个简单的代码:
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");
但是检索同一函数并通过反射调用它的行为不起作用。我怀疑这是一个特例。我找不到指示这一点的具体文档(也许这是此处所写内容的暗示(,但错误消息似乎表明使用MethodInfo
调用安全关键方法使其被视为"安全透明"。
我不知道是否有特定的解决方法,我也不知道您在这里的具体情况。我建议也许避免使用反射来获取System.Type
反射方法的MethodInfo
对象,而只使用普通委托。如果必须让它动态确定要使用的反射方法System.Type
则可以放入一个包装器,该包装器基于传入的方法名称返回编译时委托引用。例如:
if (reflectionType == "GetProperty")
{
var getPropertyInfoDelegate = new Func<string, PropertyInfo>(obj.GetType().GetType().GetProperty);
PropertyInfo propertyInfo = getPropertyInfoDelegate(propertyName);
}
或者此时,只需更直接地执行此操作:
if (reflectionType == "GetProperty")
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);
}
您可以做更多的工作来简化这一点(例如,将例程放在字典中以进行快速查找(,但是对于 Silverlight/CoreCLR 上下文,我不知道解决此问题的方法。