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
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
;
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
ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;
by yourself?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With