Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't access to internal property by reflection

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

like image 400
user278618 Avatar asked Dec 02 '11 16:12

user278618


3 Answers

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;

like image 55
vcsjones Avatar answered Sep 21 '22 21:09

vcsjones


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.

like image 22
John Fisher Avatar answered Sep 21 '22 21:09

John Fisher


Why don't you call

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

by yourself?

like image 29
codymanix Avatar answered Sep 21 '22 21:09

codymanix