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

时间:2011-12-02 16:06:57

标签: c# silverlight reflection

我有extension

 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);

是:

    (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 个答案:

答案 0 :(得分:6)

您的代码最有可能部分受信任。如果您的代码仅部分信任程序集,则无法访问内部成员,即使使用反射也是如此。您未获得部分信任的ReflectPermission

  

使用反射从部分受信任的代码访问无法从正常编译代码访问的私有,受保护或内部方法。

     

Reference

修改

  

我的应用程序的技术是Silverlight 4

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

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

但是,该财产正在做什么你可以自己做。只需使用:

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

答案 1 :(得分:2)

如果信任问题不在你的方式,你可能会遇到一个问题,你正在访问的属性是继承的。弹出打开Reflector或ILSpy以查看属性是否实际定义在您正在反映的类型上。如果不是,请尝试使用FlattenHierarchy绑定标志,或者遍历类型的父项。

答案 2 :(得分:2)

你为什么不打电话

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

自己?