safe (справочник по C#)

Контекстное safe ключевое слово подтверждает, что объявление звучит в местах, где обновленная модель безопасности памяти требует явного выбора безопасности. Вы применяете safe в качестве модификатора в объявлении, которое компилятор не может классифицировать самостоятельно, например extern элемент или поле в структуре с явным макетом. Модификатор safe является аналогом unsafe: safe указывает, что вызывающие не нуждаются unsafe в контексте, в то время как unsafe распространяет обязательство проверять безопасность вызывающей стороны.

Important

Ключевое safe слово является частью обновленной модели безопасности памяти, предварительной версии функции в C# 15 и .NET 11. Компилятор принимает safe в качестве модификатора для extern элементов и полей явного макета. Тем не менее, нет общедоступного согласия на обновленные правила безопасности вызывающего абонента, поэтому компилятор не применяет выбор безопасности, который safe и unsafe экспресс: пропускание обоих модификаторов не создает ошибку, и ни модификатор не изменяет то, что вызывающие могут делать. Чтобы следовать этой функции, задайте для параметра компилятора LangVersion значение preview. Полный дизайн см. в спецификации функции безопасности памяти.

Экстерн-члены

Член вызывает машинный extern код, поэтому компилятор не может классифицировать его безопасность. В обновленной модели помечается каждое extern объявление, включая частичный LibraryImport метод, safe либо unsafe:

// Compiles under LangVersion preview, but the safety choice isn't enforced yet.
[LibraryImport("libc")]
internal static safe partial int getpid();

[LibraryImport("libc", StringMarshalling = StringMarshalling.Utf8)]
internal static unsafe partial nint strlen(byte* str);

getpid не принимает параметров и возвращает примитив, поэтому автор подтверждает, что вызов является безопасным, и вызывающие используют его без контекста unsafe . strlen принимает необработанный указатель на то, что машинный код расшифровывается, поэтому объявление является unsafe и распространяет обязательство вызывающим его абонентам. Опущение обоих модификаторов предназначено для ошибки в обновленной модели, но компилятор пока не применяет это правило, так как для обновленных правил нет общедоступного согласия.

Поля явного макета

В структуре с [StructLayout(LayoutKind.Explicit)]полями могут перекрываться в памяти, поэтому компилятор не может подумать о том, является ли чтение через одно поле звуком. Помечаете каждое поле такой структуры safe или unsafe:

// Compiles under LangVersion preview, but the safety choice isn't enforced yet.
[StructLayout(LayoutKind.Explicit)]
internal struct Union
{
    [FieldOffset(0)]
    internal safe int AsInt;

    [FieldOffset(0)]
    internal safe float AsFloat;
}

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

Спецификация языка C#

Дополнительные сведения см. в разделе " Небезопасный код " в спецификации языка C#. Спецификация языка является авторитетным источником синтаксиса и использования языка C#.

Сведения о проектировании обновленной модели безопасности памяти см. в спецификации функции безопасности памяти.

См. также