无法通过反射访问内部属性

5

我有一个 扩展程序

 public static T GetPrivatePropertyValue<T>(this object obj, string propName)
        {
            if (obj == null) throw new ArgumentNullException("obj");
            PropertyInfo pi = obj.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (pi == null) throw new ArgumentOutOfRangeException("propName", String.Format("Property {0} was not found in Type {1}", propName, obj.GetType().FullName));
            return (T)pi.GetValue(obj, null);
        }

我正在尝试将其用作:

menuItem.GetPrivatePropertyValue<RadMenuItem>("ParentItem");

但是我在这里遇到了错误:

    return (T)pi.GetValue(obj, null);

which is:

    (T)pi.GetValue(obj, null)   'pi.GetValue(obj, null)' threw an exception of type 'System.MethodAccessException'  Telerik.Windows.Controls.RadMenuItem

menuItemTelerik.Windows.Controls.RadMenuItem类的实例。

我想要的字段是

internal RadMenuItem ParentItem
{
    get
    {
        return ItemsControl.ItemsControlFromItemContainer(this) as RadMenuItem;
    }
}

我的代码有什么问题?是因为这个属性是内部的吗?
EDIT

这是我的堆栈跟踪:

{System.MethodAccessException: Attempt by method 'MyApp.Extensions.GetPrivatePropertyValue<System.__Canon>(System.Object, System.String)' to access method 'Telerik.Windows.Controls.RadMenuItem.get_ParentItem()' failed.
   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at MyApp.Extensions.GetPrivatePropertyValue[T](Object obj, String propName)
   at MyApp.Calendar.OnContextMenuItemClick(Object sender, RadRoutedEventArgs e)}

也许这很重要:我的应用程序技术是Silverlight 4

3个回答

6
您的代码可能只是部分受信任的。如果您的代码只是对程序集部分受信任,即使使用反射,也无法访问内部成员。在部分信任中,您没有被授予ReflectPermission

通过使用反射,可以从部分受信任的代码访问私有、受保护或内部方法,这些方法在正常编译代码中是不可访问的。

参考

编辑:

我的应用程序技术是Silverlight 4

是的,这很有帮助。Silverlight不允许跨程序集访问非公共成员(除非另一个程序集具有InternalsVisibleToAttribute)。请参阅this StackOverflow问题了解更多信息。

总之,在Silverlight中,您不能使用反射访问通常无法使用编译器访问的成员。

但是,该属性正在执行的操作您也可以自己完成。只需使用:

ItemsControl.ItemsControlFromItemContainer(obj)作为RadMenuItem


2

如果没有信任问题阻碍你,你可能会遇到一个问题,即你正在访问的属性是继承来的。 打开Reflector或ILSpy,看看该属性是否实际上定义在你反射的类型上。 如果没有,尝试使用FlattenHierarchy绑定标志,或者遍历类型的父级。


2
为什么不打电话呢?
ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

你自己做吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接