Вы должны использовать указатели (небезопасный код) в C #? - PullRequest
42 голосов
/ 25 февраля 2009

Должны ли вы использовать указатели в вашем коде C #? Каковы преимущества? Это рекомендовано The Man (Microsoft)?

Ответы [ 11 ]

36 голосов
/ 25 февраля 2009

От самого "Человека":

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

  • Работа с существующими структурами на диске
  • Сценарии Advanced COM или Platform Invoke, в которых используются структуры с указателями в них
  • Код, критичный к производительности

Использование небезопасного контекста в других ситуациях не рекомендуется.

В частности, небезопасный контекст не должен использоваться для попытки написания кода C на C #.

Внимание:

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

1024 * Ссылка *

21 голосов
/ 25 февраля 2009

Если нужно.

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

12 голосов
/ 25 февраля 2009

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

Если это какое-то руководство, я считаю себя достаточно опытным в C #, но если бы мне пришлось писать какой-нибудь небезопасный код, мне пришлось бы обратиться к spec / books / MSDN, чтобы мне было легче. Конечно, будет много людей, которые довольны небезопасным кодом, но менее знакомы с (скажем) выражениями запросов ...

6 голосов
/ 25 февраля 2009

Я бы сказал, что основные проблемы: -

  • Небезопасный код не подлежит проверке. Это означает, что код может только запускаться пользователем из полностью доверенного контекста, таким образом, если вам когда-либо понадобится, чтобы пользователь запускал код из менее чем полностью доверенного места (например, сетевой ресурс не настроен для так), ты облажался.
  • Отсутствие проверяемости (хм, не уверен, действительно ли это слово) также означает, что вы могли бы потенциально испортить память в вашей программе. Вы потенциально возвращаете в приложение целые классы ошибок - переполнение буфера, висячие указатели, yada yada yuck yuck. не говоря уже о том, что он потенциально способен повреждать структуры данных в памяти, не понимая, когда ваш указатель становится странным.
  • Если вы хотите, чтобы ваш небезопасный код имел доступ к управляемым объектам, вам нужно «закрепить» их. Это означает, что GC не может перемещать ваш объект в памяти, и, таким образом, управляемая куча может стать фрагментированной. Это влияет на производительность; поэтому всегда важно определить, не перевешивает ли какой-либо потенциальный выигрыш от этой проблемы.
  • Ваш код становится труднее понять программистам, не привыкшим к неуправляемому подходу. В таком случае они могут быть более склонны отстреливать себе ногу с помощью небезопасного кода, который дает им «свобода».
  • Вы можете писать код, безопасный для типов; это действительно скорее исключает многие преимущества хорошего теплого нечеткого управляемого языка. Теперь вы можете столкнуться с ужасными проблемами безопасности типов. Зачем делать этот шаг назад?
  • Это делает ваш код уродливее .

Я уверен, что есть еще что-то, что можно добавить в список; в общем, как сказали другие - избегайте, если вам не нужно, например, Вызов неуправляемого метода через p / invoke, который требует особого подмешивания указателя. Даже тогда маршаллер, в основном, предотвратит необходимость в этом.

«Человек» также говорит, избегайте, если не нужно, в основном.

О, хорошая статья о закреплении здесь, на MSDN , кстати.

3 голосов
/ 25 февраля 2009

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

3 голосов
/ 25 февраля 2009

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

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

2 голосов
/ 25 февраля 2009

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

Использование некоторых полезных, хорошо обоснованных идиоматических функций c или C ++ в структурах, где вам нужно обрабатывать их как байт * известной длины, опять же, наиболее полезный для хеширования.

Чрезвычайно быстрая двоичная сериализация (очень специфическая) в структурах памяти (делая это с их массивом), хотя, честно говоря, это лучше сделать, просто перейдя на C ++ / CLI.

Надо сказать, что во многих случаях задачу, требующую указателей, часто можно решить лучше, если сделать это в C ++ / CLI и затем импортировать ее в ваш c # проект как dll. Это не меняет, является ли код «безопасным» или нет, но делает более доступным набор полезных функций для работы со структурами на основе указателей. Это также позволяет вам возиться с общими типами или перечислениями, если вы действительно хотите.

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

2 голосов
/ 25 февраля 2009

Вы должны использовать их, если они вам нужны; в основном это происходит при работе с некоторыми сложными сценариями взаимодействия (например, когда я написал управляемую оболочку для DPAPI в .NET 1.0, в которой они были необходимы), но очень редко это может быть для повышения производительности (после профилирования!) с помощью stackalloc или похоже.

Это рекомендовано Microsoft, поскольку они являются разработчиками C #, и они приняли решение добавить возможность писать в нее unsafe код. Из выбора ключевого слова и требования определить методы / классы, в которых вы пишете его, используя ключевое слово, вы можете видеть, что оно не предназначено для фактической реализации.

1 голос
/ 25 февраля 2009

Сделайте это, если ваш код станет короче и понятнее.

«Следуйте своим наклонностям с должным учетом полицейского за углом». WSM

1 голос
/ 25 февраля 2009

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

...