Поделиться через


Устранение ошибок и предупреждений в небезопасных конструкциях кода

В этой статье рассматриваются следующие ошибки компилятора:

  • CS0193: оператор * или -> должен применяться к указателю данных
  • CS0196: указатель должен индексироваться только одним значением.
  • CS0208: невозможно взять адрес, получить размер или объявить указатель на управляемый тип ('type')
  • CS0209: тип локального объявления в фиксированной инструкции должен быть типом указателя
  • CS0210: необходимо предоставить инициализатор в объявлении фиксированной или using инструкции.
  • CS0211: невозможно принять адрес заданного выражения
  • CS0212: можно использовать только адрес нефиксированного выражения внутри инициализатора фиксированной инструкции.
  • CS0213: Невозможно использовать инструкцию fixed для получения адреса уже фиксированного выражения.
  • CS0214: указатели и буферы фиксированного размера могут использоваться только в небезопасном контексте.
  • CS0227: небезопасный код может отображаться только в том случае, если компиляция с помощью /unsafe
  • CS0233: "идентификатор" не имеет предопределенного размера, поэтому sizeof может использоваться только в небезопасном контексте.
  • CS0242: эта операция не определена в указателях void
  • CS0244: Ни 'is' ни 'as' недопустимы для указанных типов указателей
  • CS0254: правая сторона назначения фиксированной инструкции может не быть выражением приведения
  • CS0459: не удается принять адрес локальной переменной только для чтения
  • CS0821: неявно типизированные локальные значения не могут быть исправлены
  • CS1641: поле буфера фиксированного размера должно иметь описатель размера массива после имени поля
  • CS1642: поля буфера фиксированного размера могут быть только членами структур.
  • CS1656: Невозможно присвоить значение переменной, потому что она является типом переменной только для чтения.
  • CS1663: тип буфера фиксированного размера должен быть одним из следующих типов: bool, byteили shortintlongcharsbyteushortuintulongfloatdouble
  • CS1665: буферы фиксированного размера должны иметь длину больше нуля
  • CS1666: нельзя использовать буферы фиксированного размера, содержащиеся в нефиксированных выражениях. Попробуйте использовать фиксированную инструкцию.
  • CS1708: доступ к буферам фиксированного размера можно получить только через локальные или поля
  • CS1716: не используйте атрибут 'System.Runtime.CompilerServices.FixedBuffer' . Вместо этого используйте модификатор поля fixed.
  • CS1919: небезопасный тип "имя типа" нельзя использовать в создании объекта.
  • CS4004: невозможно await в небезопасном контексте
  • CS8812: не удается преобразовать &Method группу в тип указателя, отличного от функции.
  • CS9049: фиксированное поле не должно быть полем ссылок.
  • CS9123: оператор '&' не должен использоваться для параметров или локальных переменных в асинхронных методах.

Операции указателя и отмена ссылок

  • CS0193: Оператор * или -> должен применяться к указателю данных
  • CS0196: указатель должен индексироваться только одним значением.
  • CS0242: эта операция не определена в указателях void

Чтобы правильно использовать операции указателя, следуйте правилам разыменования, индексации и арифметическим операциям. Дополнительные сведения см. в разделе "Типы указателей " и указатели функций.

  • * -> Примените оператор только к указателям данных (CS0193). Не используйте эти операторы с неуказательными типами или указателями на функции. В отличие от C/C++, в C# невозможно разыменовать указатели функций.
  • Указатели индекса только с одним значением (CS0196). Многомерное индексирование не поддерживается на указателях.
  • Избегайте операций, которые не определены в указателях void (CS0242). Не инкрементируйте указатель void, так как компилятор не знает размер данных, на которые он указывает.

Типы указателей и управляемые типы

  • CS0208: нельзя взять адрес, узнать размер или объявить указатель на управляемый тип ('тип')
  • CS0233: "идентификатор" не имеет предопределенного размера, поэтому sizeof может использоваться только в небезопасном контексте.

Чтобы работать с указателями и sizeof оператором правильно, используйте неуправляемые типы и правильные контексты. Дополнительные сведения см. в разделе "Неуправляемые типы" и о операторе sizeof.

  • Используйте указатели только с неуправляемыми типами (CS0208). Не объявляйте указатели, не берите адрес и размер управляемых типов. Управляемые типы включают ссылочные типы и структуры, содержащие поля ссылочного типа или свойства.
  • sizeof Используйте оператор в контексте unsafe при работе с типами, размер которых не является константой времени компиляции (CS0233).

Фиксированные буферы

  • CS0209: тип локального объявления в фиксированной инструкции должен быть типом указателя
  • CS0210: в объявлении инструкции fixed или using необходимо предоставить инициализатор.
  • CS0211: невозможно принять адрес заданного выражения
  • CS0212: можно использовать только адрес нефиксированного выражения внутри инициализатора фиксированной инструкции.
  • CS0213: нельзя использовать оператор fixed для получения адреса уже фиксированного выражения.
  • CS0254: правая сторона назначения фиксированной инструкции может не быть выражением приведения
  • CS0459: не удается принять адрес локальной переменной только для чтения
  • CS0821: неявно типизированные локальные значения не могут быть исправлены
  • CS1656: Невозможно присвоить значение переменной, поскольку она имеет тип "только для чтения".

Эти ошибки возникают при неправильном использовании инструкцииfixed. Инструкция fixed предотвращает сборщик мусора от перемещения переменной, которую можно перемещать, и объявляет указатель на эту переменную. Дополнительные сведения см. в разделе "Небезопасный код и указатели".

Чтобы правильно использовать инструкцию fixed , выполните следующие действия.

  • Объявите переменную как тип указателя (CS0209).
  • Укажите инициализатор в объявлении инструкции fixed (CS0210).
  • Используйте адрес только допустимых выражений: поля, локальные переменные и разыменование указателя (CS0211). Не используйте адрес вычисляемых выражений, таких как сумма двух переменных.
  • Используйте оператор address-of для нефиксированных выражений только в инициализаторе fixed инструкции (CS0212).
  • Не используйте инструкцию fixed для уже фиксированных выражений (CS0213). Локальные переменные и параметры в unsafe методе уже расположены на стеке.
  • Не используйте выражения приведения на правой стороне выражения присваивания fixed (CS0254).
  • Не считывайте адрес локальных переменных, которые являются только для чтения (CS0459). Переменные в foreach циклах, using инструкциях и fixed инструкциях доступны только для чтения.
  • Используйте явные типы вместо var в инструкциях fixed (CS0821).
  • Не присваивайте переменным в контекстах, доступных только для чтения, таких как foreach циклы, using инструкции или fixed инструкции (CS1656).

Небезопасные ограничения контекста

  • CS0214: указатели и буферы фиксированного размера могут использоваться только в небезопасном контексте.
  • CS0227: небезопасный код может использоваться только при компиляции с параметром /unsafe
  • CS0244: ни "is", ни "as" не является допустимым для типов указателей
  • CS1919: небезопасный тип "имя типа" нельзя использовать в создании объекта
  • CS4004: нельзя ожидать в небезопасном контексте
  • CS9123: оператор '&' не должен использоваться для параметров или локальных переменных в асинхронных методах

Эти ошибки возникают при использовании небезопасных конструкций кода без правильного небезопасного контекста или при попытке операций, которые не разрешены в небезопасном коде. Дополнительные сведения см. в разделе "Небезопасный код и указатели" иключевоеunsafe слово.

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

  • Пометьте методы, типы или блоки кода, использующие указатели или буферы фиксированного размера с помощью ключевого unsafe слова (CS0214).
  • Включите параметр компилятора AllowUnsafeBlocks в параметрах проекта при использовании ключевого unsafe слова (CS0227).
  • Не используйте is или as операторы с типами указателей (CS0244). Эти операторы тестирования типов недопустимы для указателей.
  • Не используйте new оператор для создания экземпляров типов указателя (CS1919). Чтобы создать объекты в неуправляемой памяти, используйте взаимодействие для вызова собственных методов, возвращающих указатели.
  • Небезопасный код отделяется от асинхронного кода (CS4004). Создайте отдельные методы для небезопасных операций и вызовите их из асинхронных методов.
  • Не используйте оператор адреса (&) для параметров или локальных переменных в асинхронных методах (CS9123). Переменная может не существовать при завершении асинхронной операции.

Буферы фиксированного размера

  • CS1641: поле буфера фиксированного размера должно иметь описатель размера массива после имени поля
  • CS1642: поля буфера фиксированного размера могут быть только членами структур
  • CS1663: тип буфера фиксированного размера должен быть одним из следующих: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float или double
  • CS1665: буферы фиксированного размера должны иметь длину больше нуля
  • CS1666: нельзя использовать буферы фиксированного размера, содержащиеся в нефиксированных выражениях. Попробуйте использовать фиксированную инструкцию
  • CS1708: доступ к буферам фиксированного размера можно получить только через локальные или поля
  • CS1716: не используйте атрибут System.Runtime.CompilerServices.FixedBuffer. Вместо этого используйте модификатор поля "фиксированный"
  • CS9049: фиксированное поле не должно быть полем ссылок

Эти ошибки возникают при работе с буферами фиксированного размера. Буферы фиксированного размера являются массивами, внедренными непосредственно в структуры, и в основном используются для сценариев взаимодействия. Дополнительные сведения см. в разделе " Буферы фиксированного размера".

Чтобы правильно объявлять и использовать буферы фиксированного размера, выполните приведенные ниже действия.

  • Укажите размер массива после имени поля с помощью положительной целочисленной константы (CS1641, CS1665).
  • Объявляйте буферы фиксированного размера только в структуры, а не в классах (CS1642). Используйте обычный массив, если требуется поле в классе.
  • Используйте один из поддерживаемых типов элементов: bool, byteshortintlongcharsbyteushortuintulongfloatилиdouble (CS1663).
  • Используйте конструкцию fixed, чтобы закрепить содержащую структуру перед доступом к буферу (CS1666).
  • Доступ к буферам фиксированного размера только через локальные или поля, а не через промежуточные выражения (CS1708).
  • fixed Используйте модификатор полей вместо атрибута System.Runtime.CompilerServices.FixedBuffer (CS1716).
  • Не объявляйте буферы фиксированного размера как ref поля (CS9049). Буферы фиксированного размера должны быть полями значений.

Указатели функций

  • CS8812: не удается преобразовать &Method группу в тип указателя, отличного от функции

Чтобы получить указатель функции, используйте оператор адреса с явным приведением типа указателя функции. Не используйте оператор получения адреса & для назначения групп методов к void* или другим типам, не являющимся указателями на функции. Дополнительные сведения см. в указателях функций.