我有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
答案 0 :(得分:6)
您的代码最有可能部分受信任。如果您的代码仅部分信任程序集,则无法访问内部成员,即使使用反射也是如此。您未获得部分信任的ReflectPermission
。
使用反射从部分受信任的代码访问无法从正常编译代码访问的私有,受保护或内部方法。
修改强>:
我的应用程序的技术是Silverlight 4
是的,这有帮助。 Silverlight不允许跨程序集访问非公共成员(除非其他程序集具有InternalsVisibleToAttribute
。请参阅this StackOverflow问题了解更多信息。
总而言之,在Silverlight中,您不能使用反射来访问您通常无法使用编译器访问的成员。
但是,该财产正在做什么你可以自己做。只需使用:
ItemsControl.ItemsControlFromItemContainer(obj)
as RadMenuItem
;
答案 1 :(得分:2)
如果信任问题不在你的方式,你可能会遇到一个问题,你正在访问的属性是继承的。弹出打开Reflector或ILSpy以查看属性是否实际定义在您正在反映的类型上。如果不是,请尝试使用FlattenHierarchy绑定标志,或者遍历类型的父项。
答案 2 :(得分:2)
你为什么不打电话
ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;
自己?