反射方法访问异常

本文关键字:异常 访问 方法 反射 | 更新日期: 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 上下文,我不知道解决此问题的方法。