无法通过反射访问内部属性
我有一个 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
menuItem
是 Telerik.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码很可能是部分受信任的。如果程序集仅部分信任您的代码,则即使使用反射,您也无法访问内部成员。您未获得
ReflectPermission
部分信任。编辑:
是的,这有帮助。 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.EDIT:
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
;如果信任问题不妨碍您,则您可能会遇到您正在访问的财产被继承的问题。弹出打开 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.
你为什么不
自己打电话呢?
Why don't you call
by yourself?