TheTalion
@TheTalion

Почему unsafe код небезопасен и его редко используют в C#?

Интересует это потому что в С++ везде указатели и ничего страшного, вроде бы, не происходит, а в C# нужно обязательно писать, что это unsafe код. Т.е. есть ситуация - у меня есть класс с 150 переменными (int), я хочу непосредственно эти переменные менять, передавая её в другой класс, типа так:
void IncFirst(){
Storage.firstValue++;
}

Т.е. я взял и в функции указал непосредственно где находится объект, НО мне что, 150 функций таких писать чтобы обновлять каждый? Это же бред.
По логике можно сделать так:
void Inc(int* value){
value++;
}

Итого нам хватит одного метода на любое кол-во переменных, но чтобы использовать указатель нужно включить небезопасный код, но, как я понял, он несет в себя ряд проблем, таких как не подлежит отладке (насколько я помню). И везде пишут что это "Очень опасно" и "Небезопасно", хотя, в чем тут реально есть опасность? Есть, например такая фраза из статьи по теме: "Прямое использование указателей отключает систему безопасности", - что это за система безопасности-то? Т.е. не пишет сообщения об ошибках в таком коде или что?

В общем, вопрос в целом такой: в действительности unsafe код так небезопасен и страшен, как его рисуют?
  • Вопрос задан
  • 5160 просмотров
Пригласить эксперта
Ответы на вопрос 5
@mafusailmagoga
Редко unsafe используют - потому что нахрен он нужен в языке, который принципиально улучшен как раз тем что код полностью managled.

Уж всяко не в вашем примере, а ради задач посерьезнее стоит заморачиваться с unsafe.

А прямая работа с указателями исключена - потому что как раз именно с указателями в С++ случается чуть ли не больше всего ошибок у программистов.

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

Считаете себя крутым и пишущим без ошибок (хотя это и не так, 100% не так) и вам не нравятся ограничения C# - ну и не пишите на C#, в чем проблем-то?

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

С# и C++ только по синтаксису сходны.
Не нужно чисто механически привносить в один язык подход из другого языка.


Т.е. есть ситуация - у меня есть класс с 150 переменными (int), я хочу непосредственно эти переменные менять, передавая её в другой класс


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


НО мне что, 150 функций


А их и не должно быть у вас 150.
См. антипаттерн - класс Бог.
Ответ написан
@kttotto
пофиг на чем писать
Ваша задача нормально решается и без unsafe кода, без костылей и наворотов. Просто мыслить в терминах C++ и писать код на C# не совсем сопоставимо. Если хотите менять непосредственно значения, есть передача значений по ссылке, есть out и ref параметры, для 150 однотипных значений есть массивы, есть списки (и для разнотипных) . Просто нужно подумать в рамках идеологии C#.

Хотя мне не совсем понятна проблема изменить переменные в классе и зачем для этого писать 150 методов. Класс это же объект, который передается по ссылке. Передав объект, Вы будете менять эти переменные у объекта как хотите. Если хотите передать куда-то непосредственно поле класса типа int и хотите, чтоб оно изменилось там, то передайте его как out/ref параметр.
Ответ написан
@d-stream
Готовые решения - не подаю, но...
Кто триппером не болел - тот не гусар -)

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

Как показывает практика - даже у старух бывают фейловые прорухи. Зачастую глобальных масштабов.
Как примеры - те же до сих пор появляющиеся уязвимости на переполнении стека и прочих классических штук времен Моррисона
Ответ написан
Griboks
@Griboks Куратор тега C#
Всё можно сделать и без указателей. Например, с помощью индексаторов либо массивов. Вы не знаете, как в массиве задать геттеры и сеттеры (get; set;)? Прочитайте побольше о свойствах и узнаете, что это есть ни что иное, как методы доступа к скрытым переменным.
Ответ написан
@Ivankon
Обратите внимание на новые возможности языка C# 7.0 там появились безопасные указатели:
https://docs.microsoft.com/en-us/dotnet/csharp/wha...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы