Почему вообще возможно изменить закрытый член или запустить закрытый метод в C #, используя отражение? [Дубликат]

На этот вопрос уже есть ответ здесь:

Почему отражение доступа защищенного / частного члена класса в C #? 3 ответа

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

Я был ошеломлен, узнав, что установка частного члена / поля, а также запуск частного метода - это вещи, которые разрешены и возможны в C #. Это не вопрос того, как делать эти вещи, они хорошо документированы, мой вопрос: почему?

Если вы установите поле / член / метод как личное / внутреннее, почему C # как язык позволяет устанавливать эти поля вне области? Я думал бы, что это бросило бы исключение некоторого вида. Если класс хочет, чтобы они были изменены или установлены, не будетЕсть ли метод или конструктор?

 Eyvind06 июн. 2013 г., 15:57
@ Shaamaan Я думаю, вы никогда не доверяете при работе в браузере.
 Renan05 июн. 2013 г., 16:12
@ MichaelKjöсейчас восемь.
 Vince Panuccio12 июн. 2013 г., 04:51
Если оно'С твоей безопасностьюпосле, поиск Google для ".NET Code Access Security "
 Daren Thomas05 июн. 2013 г., 16:16
@hvd, я должен с тобой согласиться ...
 Chris Dunaway05 июн. 2013 г., 17:31
Просто чтобы быть педантичным, C # язык, неЯ не могу этого допустить. Классы в пространстве имен System.Reflection не являются специфичными для C #.
 Ani05 июн. 2013 г., 16:12
 Patashu05 июн. 2013 г., 16:09
Как только вы используете Reflection, ручной байт-код и т. Д. Вы 'говорятНаполните нормальную объектно-ориентированную модель, мне нужно это сделать, и мне нужно сейчас, Это означает, что обычные ограничения сняты, поскольку вы ясно даете понять, что хотите их обойти. С большой властью приходит большая ответственность.
 Jeppe Stig Nielsen05 июн. 2013 г., 18:00
@ 11684 Вы должны дать ссылку на этот вопрос в своем комментарии. Тогда две темы будутсвязано".
 Damien_The_Unbeliever07 июн. 2013 г., 14:10
Я неЯ не знаю, почему этот вопрос оказался таким популярным, но спасибо, что задали его :-)
 Quibblesome06 июн. 2013 г., 14:24
@ Эйвинд, яЯ уверен, что раньше. Я либо испортил код, либо они его исправили.
 user74338205 июн. 2013 г., 16:11
Тот'не так ли? Во время выполнения модификаторы доступа обычно также проверяются. Просто попробуйте: создайте программу и библиотеку, попросите программу использовать что-то из библиотеки, измените доступ к частному в библиотеке и запустите программу без перекомпиляции. Вы'Я получу исключение во время выполнения.
 Quibblesome05 июн. 2013 г., 18:50
Кроме того, рассмотрим прелести этого небольшого фрагмента: typeof (String) .GetField ("Пустой», BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField) .SetValue (null, "Foo» );
 Daren Thomas05 июн. 2013 г., 16:09
Предположение: Reflection работает не на языке (c #), а на среде выполнения (MSIL) и, следовательно, ограничения, установленные компилятором, не применяются ...
 Vince Panuccio18 июн. 2013 г., 04:45
@ Amy Они не отказываются от поддержки, это 'Все еще там, вам просто нужно включить его. Так сказано в ссылке, которую вы разместили.
 Eyvind06 июн. 2013 г., 09:25
@Quibblesome По некоторым причинам, это действительно не работает. В противном случае была бы отличная шутка!
 1168405 июн. 2013 г., 16:33
Подобный вопрос уже задавался на SO, единственное отличие заключалось в том, что языком, используемым OP этого вопроса, была Java вместо C #. Но они достаточно похожи, чтобы использовать ответы на этот вопрос для них обоих.
 Shaamaan06 июн. 2013 г., 10:34
Безразлично»Тебе не кажется странным, что Silverlight препятствует доступу к закрытым полям и методам даже при использовании Reflection? И я думаю, что Silverlight по-прежнему квалифицируется как C # и .NET, нет?
 Amy16 июн. 2013 г., 17:20
@VincePanuccio: Microsoft отказывается от CAS:infoq.com/news/2009/11/CAS-Replaced
 Raymond Chen05 июн. 2013 г., 17:45
Отладчики не были бы очень полезны, если бы они не моглиДоступ к закрытым членам класса, который вы отлаживаете.
 Eyvind06 июн. 2013 г., 15:56
@Quibblesome Ну, любопытно, что отладчик показывает значение String.Empty, чтобы быть "Foo» (т.е. если вы наводите курсор мыши), но реальный код все равно обрабатывает его как «».
 a CVn05 июн. 2013 г., 16:13
@ Ренан Или девять. Это становится параболическим. Я'м отсюда. ;)

Ответы на вопрос(9)

Случай в производственном коде:

Мы хотели, чтобы один веб-сервис работал в часовом поясе Новой Зеландии. Вероятно, правильное решение - переписать весь наш код (включая некоторый код сериализации .NET Framework) для использованияDateTimeOffset, но самым простым решением было эффективно настроить два приватных поля в .NET Framework, в которых хранится текущий часовой пояс (обычно основанный на вызовах реестра), чтобы явно использовать часовой пояс NZ.

Мы знаем, что если .NET Framework версии 2.0 когда-либо обновляет свою обработку часовых поясов, нам, возможно, придется переделать наш код, но на данный момент он работает нормально в производстве.

Модификаторы видимости не являютсяТ предназначен для безопасности.

Они просто предназначены для работы со структурированным APIs / codebases более эффективны - чтобы не утомлять программиста болтовней - и раскрывать только то, что должно интересовать потребителей.

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

Если бы я был болен, я, возможно, уже был бы мертв, когда врачам нужны рентгеновские лучи, чтобы диагностировать и лечить мою болезнь, но всевозможные размышления не могут увидеть то, что является частным для меня. И я никогда себя не вижу.

Рентген (или что-тотомография-подобно) могу наблюдать за собой, что я никогда не смогу сделать без него.

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

Итак, рефлексия должна относиться к реалистичной, без определенной точки зрения. И вы можете предположить, что код потребителей ограничен BindingFlags.Public в рамках правил объектной ориентации.

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

Кажется опасным, что отражение может делать все во вселенной программ, и теперь этонеобходимо полностью доверять по соображениям безопасности человекулогика

Отражение - это то, как вы взаимодействуете со скомпилированным кодом. Если рефлексия уважала исходный языкожидания в отношении конфиденциальности, был бы необходим другой механизм, такой как он, который нет. Черепахи все время вниз.

Начните с предположения, что это то, что он делаетЭто значит, а затем пересмотреть ваше предположение, что это было ошибочное усилие сделать что-то другое, что никто не хочет делать в любом случае.

Частное размышление требует, чтобы вам было предоставлено практически полное доверие. Полное доверие означаетполное доверие, Если ты'полностью доверяют тому, чтобы поступать правильно, тогда почемуэто работа?

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

 Mike Perrenoud05 июн. 2013 г., 16:23
Теперь это самая ясность, которую яВидел по частному размышлению когда-либо. Это требуетполное довериеСпасибо, Эрик!
 Eric Lippert05 июн. 2013 г., 16:39
@ Майкл, на самом деле все немного сложнее на практике. Я упрощаю, чтобы прояснить суть; эта возможность контролируется политикой.
 Mike Perrenoud05 июн. 2013 г., 16:41
этот маленький самородок в вашем комментарии, хотяcontrolled by a policy тоже огромен - это имеет смысл - и хотя я неЯ не могу до конца понять, что это дает мне понять, что сетевые администраторы могут также контролировать эту политику, поэтому я не долженя предполагаю, что яЯ всегда буду иметь доступ к частным размышлениям. Опять же, нужно немного почитать, но это был отличный самородок. Большое спасибо!

Иногда приходится обманывать.

Это'Легко сказать, что класс должен иметь установщик чего-то, если это нужно установить, но что, если вы можете 'т добавить? Что если этоэто не твой класс, этоs проприетарная библиотека и вам нужно обойти ошибку в ней? Я'Я не говорю, что тыдолжен делать такие вещи, на самом деле я бы сказал, что вы почти наверняка не должныт, но иногда единственный способ заставить что-то работать - это возмутительное мошенничество. В этих случаях тот факт, что эти механизмы существуют, чрезвычайно полезен.

Вы должны, однако,всегда сомневайтесь в их использовании и, конечно же, помните, что нарушение общедоступного API объекта может вызвать проблемы в дальнейшем и, вероятно, является неправильным решением. За исключением вышеупомянутого сценария, когдаединственный способ заставить что-то работать в каком-то коде, который вы неу меня есть возможность измениться.

Следует отметить, что C ++ и его производные имеют строгий контроль доступа, но существует множество языков ООП, которые нет. Например, объекты Perl 5 полностью открыты для вмешательства извне, а частные методы и данные существуют только по соглашению - программист на Perl знает, что возиться внутри стороннего объекта 's hashref, вероятно, собирается что-то сломать, поэтому они обычно побеждаютсделать это. Опять как с C # 'Однако, вы можете решить очень много проблем, немного подправив что-нибудьна самом деле не должен трогать.

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

Хороший вопрос.

Мой ответ будет таким: Модификаторы доступа и видимость являются частью дизайна API. Благодаря отражению вы получаете полный контроль над практически всем, включая обход API и изменение данных на низком уровне.

Модификаторы доступа могут защитить ваши классы от случайных изменений извне. Вы можете вызвать метод или получить доступ к публичному членуслучайно", С размышлением трудно утверждать, что вы сделали что-то случайно.

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

Этоневозможно чтобы кто-то не смог этого сделать. Вы можете сделать это сложнее, вы можете заставить их использовать небезопасный код и начать устанавливать биты вслепую. В конце концов, этоИх программа / машина, ониразрешено делать такие вещи.

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

 Mike Perrenoud05 июн. 2013 г., 16:12
Это мой любимый ответ. Модификация значений - это просто механизм доступа к памяти.профилактика / удаление вирусов рынок. Идея в том, что если вы сделаете что-то менее заметным для потребителей, они поймут, чтовообще говоря тот'как интерфейсдолжен быть использован. Это также означает, что изменение данных черезReflection может вызвать нестабильность(хотя я'мы сделали это) : D
 Scott Wisniewski06 июн. 2013 г., 00:46
Это'не невозможно. Просто очень сложно. Например, вы можете запустить программу так, чтобы каждый доступ к памяти был перехвачен (с помощью mmu) и проверен либо отдельным процессом (с использованием API отладки), либо через ядро или какой-либо монитор vm. Такие программы мониторинга могут анализировать доступ к памяти и принимать очень сложные политические решения. Это было бы очень медленно, но это возможно.
 grinch06 февр. 2014 г., 14:19
@ScottWisniewski, что если кто-то также попытается изменить память программного обеспечения, обеспечивающего политику доступа, чтобы оно давало им доступ для изменения другого процесса? :п
Решение Вопроса

Потому что есть модификаторы доступа, чтобы помочь с документированием API, который выхочу выставлять потребителям или наследникам и т. д.

Oни'рене механизм безопасности / контроля доступа.

 Servy05 июн. 2013 г., 16:22
@Patashu И даже если это неЕсли бы вы не существовали, вы все равно могли бы вызывать, например, код C ++, который может вращаться в любом месте процесса »память твоей волей неволей. В конце дня вы можетене позволяет программе манипулировать еюсобственное пространство памяти; для того, чтобы иметь возможность функционировать вообще, ему нужно иметь достаточный доступ, чтобы делать практически все, что он хочет, с этой памятью.
 Patashu05 июн. 2013 г., 16:12
Я думаю, что существование ключевого словаunsafe означает, что даже если Reflection не существует, вы можете получить доступ к закрытым полям типа данных C #. (Я'Я не игра, чтобы попробовать)
 Brian05 июн. 2013 г., 19:00
Я неЯ думаю, что совершенно справедливо сказать, что модификаторы доступа не являются механизмом контроля доступа, хотя они и неt обеспечить безопасность типа, обсуждаемого ФП. УвидетьУровни доступа и модификаторы (закрытый, закрытый и т. Д.) Служат целям безопасности в C #? , Пер Эрик Липперт: «Ограничения доступа смягчают атаки на ваших пользователей с помощью частично доверенного враждебного кода ».

Ваш ответ на вопрос