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

发布于 2024-12-19 06:15:45 字数 2613 浏览 1 评论 0原文

我有一个 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

I have an 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);
        }

and I'm trying to use it as:

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

but I get an error at:

    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

menuItem is an instance of Telerik.Windows.Controls.RadMenuItem class

and the field I want is

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

What is wrong my code? It's because this property is internal?

EDIT

This is my stacktrace:

{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)}

And maybe it is important: technology of my application is Silverlight 4

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

反话 2024-12-26 06:15:45

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

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

参考

编辑

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

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

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

但是,该属性正在做什么你可以自己做:

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

Your code is partially trusted, most likely. You cannot access internal members, even with reflection, if your code is only partially trusted to the assembly. You are not granted the ReflectPermission in partial trust.

A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially trusted code by using reflection.

Reference

EDIT:

technology of my application is Silverlight 4

Yes, that helps. Silverlight does not allow access to non-public members across assemblies (Unless the other assembly has an InternalsVisibleToAttribute. See this StackOverflow question for more.

To sum it up, in Silverlight, you can not use reflection to access members that you normally wouldn't be able to access with the compiler.

However, what that property is doing you can do yourself. Just use:

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

别闹i 2024-12-26 06:15:45

如果信任问题不妨碍您,则您可能会遇到您正在访问的财产被继承的问题。弹出打开 Reflector 或 ILSpy 以查看该属性是否实际上是在您要反射的类型上定义的。如果不是,请尝试使用 FlattenHierarchy 绑定标志,或迭代类型的父级。

If trust issues are not in your way, you may be running into a problem where the property you're accessing is inheritted. Pop open Reflector or ILSpy to see if the property is actually defined on the type you're reflecting. If it isn't, try playing with the FlattenHierarchy binding flag, or iterate through the type's parents.

旧时光的容颜 2024-12-26 06:15:45

你为什么不

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

自己打电话呢?

Why don't you call

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

by yourself?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文