2010-05-03 3 views
9

Прочитайте this question сегодня о безопасном и небезопасном коде. Затем я прочитал об этом в MSDN, но я до сих пор этого не понимаю. Почему вы хотите использовать указатели в C#? Это чисто для скорости?Safe vs Небезопасный код

+15

Если вы разумный человек, то вы никогда не * хотите * использовать указатели в C#. Они существуют в тех ситуациях, когда вы * имеете * использовать указатели на C#, хотите ли вы * хотите или нет. :-) –

ответ

22

Есть три причины использовать небезопасный код:

  • APIs (как отмечает Джон)
  • Получение фактического адреса памяти данных (например, доступ к памяти, отображенные аппаратную)
  • Наиболее эффективный способ доступа и изменения данных (требования к рабочим характеристикам, критичных ко времени)
+6

Для критически важных приложений, использующих .net, в любом случае не является умным. GC не является детерминированным и может ударить в каждый момент. Который в основном завинчивает ваше критически важное приложение. Другие пункты, которые я согласен кстати! – Henri

+1

Еще одна причина, по которой я слышал, ссылаясь на использование небезопасного C#, заключается в том, что конфиденциальная информация, например пароль или закрытый ключ шифрования, удаляется из памяти в детерминированный момент времени. В противном случае пароль может зависеть в памяти, пока кто-то еще не захочет писать в тех же местах. – harms

+1

Это также иногда полезно в университетских проектах. –

5

Иногда вам понадобятся указатели для взаимодействия вашего C# с базовой операционной системой или другим родным кодом. Вам категорически не рекомендуется делать это, так как это «небезопасно» (natch).

Будут некоторые очень редкие случаи, когда ваша производительность настолько привязана к процессору, что вам нужна эта небольшая дополнительная производительность. Моя рекомендация заключалась бы в том, чтобы написать эти CPU-интуитивные фрагменты в отдельном модуле на ассемблере или C/C++, экспортировать API, и ваш код .NET вызывает этот API. Возможным дополнительным преимуществом является то, что вы можете поместить код, специфичный для платформы, в неуправляемый модуль и оставить агностику платформы .NET.

+1

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

+0

Правильный инструмент для правильной работы? Если я собираюсь обезьяна с указателями и другими низкоуровневыми работами, я бы предпочел сделать это с C/C++, где у меня есть много инструментов в моем распоряжении. Полезные вещи, такие как встроенный ассемблер, указатели на основе и другие элементы, способные перетаскивать бит, не поддерживаются в C#. –

+0

Я согласен, что при написании на ассемблере или C вы должны быть обеспокоены тем, как был скомпилирован код. – ChaosPandion

4

Склоняюсь, чтобы избежать этого, но есть некоторые моменты, когда это очень полезно:

  • для выполнения работы с сырьем буферов (графиками и т.д.)
  • необходимо для некоторого неуправляемого API (также довольно редко для меня)
  • за обман с данными

К примеру последних, Я поддерживаю некоторый код сериализации. Дать float в поток без использования BitConverter.GetBytes (который создает массив каждый раз) больно - но я могу обмануть:

float f = ...; 
int i = *(int*)&f; 

Теперь я могу использовать сдвиг (>>) и т.д., чтобы писать i гораздо легче, чем запись f будет (байты будут идентичны, если бы я вызвал BitConverter.GetBytes, плюс теперь я контролирую сущность, как я выбираю использовать сдвиг).

+3

Я понимаю, почему вы это делаете, но этот код на C# просто заставляет меня съеживаться. – Stephan

+0

Мне просто пришлось смеяться, когда я увидел это: «для обмана с данными». Ты меня взломаешь, мой друг! Я не могу сказать, что я когда-либо делал это, но пример имеет прекрасный смысл! –

0

Существует, по крайней мере, один управляемый API .Net, который часто делает использование указателей неизбежным. См. SecureString и Marshal.SecureStringToGlobalAllocUnicode.

только способ получить простое текстовое значение SecureString является использование одного из Marshal методов, чтобы скопировать его в неуправляемую память.

Смежные вопросы