Частные методы, использующие .NET отражение. Зачем? - PullRequest
3 голосов
/ 28 ноября 2009

Я много раз размышлял над публичными методами, но никогда не понимал, что частные методы тоже можно вызывать. См. Отражение с личными членами .

Почему это разрешено в первую очередь? Разве это не нарушит правило «частный» быть «частным»?

Ответы [ 5 ]

4 голосов
/ 28 ноября 2009

Это разрешено только в том случае, если код выполняется с полным доверием (или с соответствующим разрешением). В противном случае будет выброшено MethodAccessException.

Фреймворк вполне может надлежащим образом ограничить доступ - он просто этого не делает, когда вы работаете с полным доверием или когда у вас есть определенные разрешения. См. «Вопросы безопасности при отражении» для получения более подробной информации о том, когда вы можете сделать это.

4 голосов
/ 28 ноября 2009

private в C # действительно является лишь частью спецификации языка; на языке C #, а также на языке Visual Basic или любом другом приемлемом языке .NET (включая CIL , на котором собраны все языки .NET), одному из них запрещен доступ к private (или protected, если вы не в производном классе) участник на языке . Однако тот факт, что язык не поддерживает публичный доступ к private или protected членам, не означает, что базовая структура не может предоставить доступ к этим членам.

Это один из тех случаев, когда обычно не должен использовать обходные пути, такие как отражение, для доступа к элементам private или protected или их изменения, но каркас позволяет в любом случае. Как правило, у вас должна быть очень веская причина для доступа к private или protected членам; одна из таких причин, например, заключается в реализации сериализатора, который должен смотреть на внутреннее состояние объекта для правильной сериализации объекта. Если вы не делаете что-то подобное, вам следует по-настоящему взглянуть на переопределение класса, внутри которого вы ковыряетесь, чтобы вам не нужно было использовать отражение в вашей программе.

1 голос
/ 06 июля 2012

Reflection - это мощная функциональность в .NET, но у нее есть и свои недостатки.

Плюсы:

  1. Reflection разрешает доступ всем членам (включая частных и защищенных), при условии, что у вас есть хотя бы защита ReflectionPermission . (Это разрешение можно получить, когда ваше приложение обращается к отраженной сборке с того же диска, а не из Интернета.)

  2. В некоторых редких случаях рефлексия - единственный способ выполнить задачу.

Минусы:

  1. Отражение нарушает безопасность (как и декомпиляция сборки). Чтобы обеспечить полную безопасность кода и данных вашего приложения, вы должны использовать криптографию, а не полагаться только на ключевые слова Private или Protected, поскольку, если они одни, их можно легко взломать с помощью отражения или декомпиляции.

  2. Отражение намного медленнее и потребляет больше ресурсов, чем статические ссылки (обычный способ вызова методов). По этой причине вам следует избегать размышлений, если только это не единственный способ решить вашу проблему.

Примеры , когда отражение является единственным способом решения проблемы:

  1. Предположим, что ваше приложение динамически компилирует код (например, когда вы чертите функции, которые пользователь предоставляет во время выполнения). В таких случаях единственный способ загрузить сборки и типы - это отражение.

  2. Вы хотите клонировать объект. Вам нужно использовать отражение для доступа к своим личным полям.

Надеюсь, это поможет. Я должен поблагодарить г-на Франческо Балена за его прекрасную книгу «Программирование Microsoft Visual Basic 2005: Язык».

1 голос
/ 28 ноября 2009

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

Есть несколько мест, где это может быть полезно:

  • Тестирование устаревшего кода - Например, предположим, что вы работаете с устаревшим кодом и хотите покрыть его модульными тестами. Если вам не разрешено изменять код и вы хотите протестировать небольшую часть функциональности, полезно использовать закрытые методы.
  • Хаки в рабочем коде - Однажды я столкнулся с ошибкой в ​​стороннем контроле, когда в каком-то сценарии частная очистка не выполнялась. Используя приватный вызов, я мог бы обойти это.

Нет ничего плохого в том, что фреймворк предоставляет эту функциональность, но использовать его там, где это не обязательно, неправильно.

1 голос
/ 28 ноября 2009

Да, это нарушает правило. Я бы почти никогда не передавал код во время проверки, если бы кто-то сделал это.

Использование рефлексии для вызова метода slllloooow, небезопасно и легко прерывается, если базовый класс переработал закрытые методы.

Короче, я согласен, это плохая идея!

...