C #: Преимущество явного указания опции «небезопасно» / компилятор - PullRequest
8 голосов
/ 03 марта 2009

Я понимаю указатели и редкую необходимость использовать их в коде C #. Мой вопрос: в чем причина необходимости явно указывать «небезопасно» в блоке кода. Кроме того, почему необходимо изменить параметр компилятора, чтобы разрешить «небезопасный» код?

Итог: Что в CLR (или спецификациях языка) делает это так, что мы не можем просто использовать указатели, когда захотим (так же, как C и C ++) без необходимости вводить «unsafe» и изменять опция компилятора?

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

Ответы [ 9 ]

9 голосов
/ 03 марта 2009

Есть интервью с C # Creator Андерсом Хейлсбергом, которое затрагивает тему здесь . По сути, именно то, что сказал @Marc Gravell: безопасность типов во-первых, безопасность посредством явного объявления.

Итак, чтобы ответить на ваш вопрос: ничто в CLR не мешает этому; Это языковая идиома, позволяющая вам работать с защитными перчатками при работе с типами. Если вы хотите снять перчатки, это ваш выбор, но вы должны сделать активный выбор, чтобы снять перчатки.

Edit:

Для уточнения: я знаю, что «небезопасный» и «безопасный» код есть. Это просто вопрос, почему мы должны делать все дополнительная работа (хорошо, не слишком много) просто чтобы иметь возможность использовать эти функции.

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

Так что «дополнительная работа» является намеренной, чтобы заставить вас подумать о том, что вы делаете, прежде чем делать это. Будучи явным, он заставляет вас хотя бы подумать: «Зачем я это делаю? Нужен ли мне действительно указатель, когда будет достаточно ссылочного типа?"

7 голосов
/ 03 марта 2009

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

Это становится более заметным при частичном доверии (надстройки и т. Д.), Но все еще полезно в обычном коде.

3 голосов
/ 03 марта 2009

На самом деле CLR вообще не предъявляет никаких требований к ключу / unsafe. Фактически, C ++ / CLI (язык C ++, который работает под CLR) не имеет такого / небезопасного переключателя, и указатели могут свободно использоваться в CLR.

Итак, я бы перефразировал ваш вопрос как "Почему C # требует использования / unsafe перед использованием указателей?" И ответ на этот вопрос такой же, как указано в других ответах, приведенных здесь: чтобы помочь пользователю принять осознанное решение потерять способность работать в режиме, отличном от режима полного доверия в CLR. C ++ практически всегда требует полного доверия на CLR, а C # может всякий раз, когда вы вызываете код, требующий полного доверия, или всякий раз, когда вы используете указатели.

2 голосов
/ 03 марта 2009

Короче говоря .NET хочет, чтобы вы заявили о своих намерениях.

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

Для меня это сродни ряду синтаксических требований в C #:

  • без корпуса переключателя без разрыва
  • нет "разделов" уровня доступа (таких как "public:" в C ++)
  • нет полей класса, использующих "var"

Суть в том, что вы не должны двигаться или менять одну вещь и непреднамеренно влиять на другую. В разумных пределах они хотят помешать вам «выстрелить себе в ногу».

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

2 голосов
/ 03 марта 2009

Подумайте об этом с противоположной точки зрения: поскольку он не помечен как небезопасный, вы можете сделать вывод, что большая часть кода по умолчанию является «безопасной». Так что же значит быть «безопасным»? Для кода .Net это включает (но не ограничивается):

  • Сборщик мусора может вести дела как обычно.
  • Ссылки на определенный тип будут ссылаться на объекты этого типа (или ноль).
  • Код гарантированно соответствует требованиям .Net доверия / безопасности.
  • Математически доказано, что код не касается непосредственно памяти вне его собственного домена приложений. Это может показаться тривиальным, но представьте, если у вас есть несколько доменов приложений в одном приложении. Программист может с уверенностью относиться к ним как к логически раздельным.

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

2 голосов
/ 03 марта 2009

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

1 голос
/ 03 марта 2009

Самое существенное различие между безопасным и небезопасным кодом заключается в том, что небезопасный код недоступен сборщику мусора .net. Автоматический сборщик мусора - огромная часть языка .net, и когда вы выходите за его пределы, вы многое изменяете в своем коде.

В частности, указатели позволяют создавать объекты в куче без ссылок GC. Это приводит к еще одной веской причине, по которой код должен быть помечен как «небезопасный». Это позволяет легко определить источник утечки памяти, когда вы понимаете, что она есть.

1 голос
/ 03 марта 2009

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

1 голос
/ 03 марта 2009

Так что сразу видно, какой код не будет работать в веб-сервисах без повышенных разрешений и т. Д.

...