2009-11-28 4 views
3

Я использовал отражение много раз перед публичными методами, но я никогда не думал, что частные методы также могут быть вызваны. См. Reflection with private members.Частные методы, использующие отражение .NET. Зачем?

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

+0

Ссылка не работает. Переместилось ли оно куда-то еще? –

ответ

3

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

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

1

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

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

Итак, я согласен, это плохая идея!

+0

странно. почему они позволили бы это ... внезапно, мир уже не безопасен;) –

1

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

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

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

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

3

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

Рамка отлично подходит для ограничения доступа - она ​​просто не делает этого, когда вы работаете под полным доверием или когда у вас есть определенные разрешения. См. "Security Considerations for Reflection" для получения дополнительной информации о том, когда вы в состоянии это сделать.

1

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

Плюсы:

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

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

Минусы:

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

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

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

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

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

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