Не могу получить доступ к внутренней собственности по отражению - PullRequest
4 голосов
/ 02 декабря 2011

У меня есть 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

Ответы [ 3 ]

6 голосов
/ 02 декабря 2011

Ваш код, скорее всего, частично доверенный.Вы не можете получить доступ к внутренним элементам, даже с отражением, если ваш код только частично доверяет сборке.Вам не предоставляется ReflectPermission при частичном доверии.

Частный, защищенный или внутренний метод, который не был бы доступен из обычного скомпилированного кода, доступен из частично доверенного кода.используя отражение.

Ссылка

РЕДАКТИРОВАТЬ :

Технология моего приложения - Silverlight 4

Да, это помогает.Silverlight не разрешает доступ к закрытым элементам в разных сборках (кроме случаев, когда у другой сборки есть InternalsVisibleToAttribute. Подробнее см. этот вопрос StackOverflow .

Чтобы подвести итог, в Silverlightвы не можете использовать отражение для доступа к членам, к которым вы обычно не можете получить доступ с помощью компилятора.

Однако, то, что делает это свойство, вы можете сделать сами. Просто используйте:

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

2 голосов
/ 02 декабря 2011

Почему бы вам не позвонить

ItemsControl.ItemsControlFromItemContainer(obj) as RadMenuItem;

самостоятельно?

2 голосов
/ 02 декабря 2011

Если проблемы доверия вам не мешают, вы можете столкнуться с проблемой, когда свойство, к которому вы обращаетесь, наследуется.Откройте Reflector или ILSpy, чтобы увидеть, действительно ли свойство определено для отображаемого вами типа.Если это не так, попробуйте поиграть с флагом привязки FlattenHierarchy или переберите родителей этого типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...