Устранение ошибок и предупреждений с помощью встроенных объявлений массива
В этой статье рассматриваются следующие ошибки и предупреждения компилятора:
- CS9164: не удается преобразовать выражение
Span<T>
, так как оно не является назначаемой переменной - CS9165: не удается преобразовать выражение
ReadOnlySpan<T>
, так как оно не может быть передано или возвращено по ссылке - CS9166: индекс находится за пределами границ встроенного массива
- CS9167: длина встроенного массива должна превышать 0.
- CS9168: структура встроенного массива не должна иметь явного макета.
- CS9169: структура встроенного массива должна объявлять одно и только одно поле экземпляра, которое не должно быть полем ссылок.
- CS9172: к элементам встроенного типа массива можно обращаться только с одним аргументом, неявно преобразованным в
int
,System.Index
илиSystem.Range
. - CS9173: доступ к встроенному массиву может не иметь именованного описателя аргументов
- CS9180: поле элемента встроенного массива не может быть объявлено как обязательное, чтение, переменная или как буфер фиксированного размера.
- CS9181: индексатор встроенных массивов не будет использоваться для выражения доступа к элементам.
- CS9182: метод встроенного массива "Срез" не будет использоваться для выражения доступа к элементам.
- CS9183: оператор преобразования встроенных массивов не будет использоваться для преобразования из выражения декларающего типа.
- CS9184: функция языка встроенных массивов не поддерживается для встроенных типов массивов с полем элемента, которое является полем "
ref
" или типом, недопустимым в качестве аргумента типа. - CS9189:
foreach
оператор в встроенном массиве типов не поддерживается - CS9259: атрибут System.Runtime.CompilerServices.InlineArrayAttribute не может применяться к структуре записи.
Объявление встроенного массива
Встроенные массивы объявляют как struct
тип с одним полем и атрибутом, указывающим длину массива. Компилятор создает следующие ошибки для недопустимых объявлений встроенного массива:
- CS9167: длина встроенного массива должна превышать 0.
- CS9168: структура встроенного массива не должна иметь явного макета.
- CS9169: структура встроенного массива должна объявлять одно и только одно поле экземпляра, которое не должно быть полем ссылок.
- CS9180: поле элемента встроенного массива не может быть объявлено как обязательное, чтение, переменная или как буфер фиксированного размера.
- CS9184: функция языка встроенных массивов не поддерживается для встроенных типов массивов с полем элемента, которое является полем "
ref
" или типом, недопустимым в качестве аргумента типа. - CS9259: атрибут System.Runtime.CompilerServices.InlineArrayAttribute не может применяться к структуре записи.
Чтобы исправить эти массивы, убедитесь, что следующие значения:
- Аргумент является System.Runtime.CompilerServices.InlineArrayAttribute положительным целым числом.
- Заключение
struct
не указывает явный макет. struct
Заключенный имеет одно поле экземпляра, и это поле экземпляра не является полемref
.- Поле одного экземпляра не является буфером фиксированного размера.
- Поле одного экземпляра не включает
required
volatile
модификаторы , илиreadonly
модификаторы. - Удалите модификатор из объявления встроенного
record
массива.
Доступ к элементам
Доступ к элементам встроенного массива выполняется так же, как и к любому массиву. Компилятор выдает следующие ошибки из неправильного доступа к элементу:
- CS9166: индекс находится за пределами границ встроенного массива
- CS9172: к элементам встроенного типа массива можно обращаться только с одним аргументом, неявно преобразованным в
int
,System.Index
илиSystem.Range
. - CS9173: доступ к встроенному массиву может не иметь именованного описателя аргументов
- CS9189:
foreach
оператор в встроенном массиве типов не поддерживается
Кроме того, компилятор выдает следующее предупреждение при объявлении индексатора:
- CS9181: индексатор встроенных массивов не будет использоваться для выражения доступа к элементам.
Созданный код для встроенного буфера обращается к памяти буфера напрямую, обходя объявленные индексаторы. Встроенные массивы нельзя использовать с инструкцией foreach
.
Аргумент индексатора должен быть следующим:
- Один из трех типов:
int
, aSystem.Index
или aSystem.Range
. - Не может быть именованным аргументом. Компилятор создает метод доступа к элементу. Параметр не имеет имени, поэтому нельзя использовать именованные аргументы.
- Включается в границы массива. Как и все массивы .NET, доступ к элементу встроенного массива проверяется. Индекс должен находиться в пределах встроенного массива.
Преобразования в диапазон
Часто используется System.Span<T> или System.ReadOnlySpan<T> работает с встроенными массивами. Компилятор создает следующие ошибки для недопустимых преобразований:
- CS9164: не удается преобразовать выражение
Span<T>
, так как оно не является назначаемой переменной - CS9165: не удается преобразовать выражение
ReadOnlySpan<T>
, так как оно не может быть передано или возвращено по ссылке
Компилятор создает код, который напрямую обращается к памяти для встроенного буфера. Поэтому некоторые члены никогда не вызываются. Компилятор создает следующие предупреждения при написании одного из элементов, которые никогда не вызываются:
- CS9182: метод встроенного массива "Срез" не будет использоваться для выражения доступа к элементам.
- CS9183: оператор преобразования встроенных массивов не будет использоваться для преобразования из выражения декларающего типа.
Встроенный массив может быть неявно преобразован в объект Span<T>
или ReadOnlySpan<T>
передавать встроенный массив в методы. Компилятор применяет ограничения для этих преобразований:
- Для преобразования встроенного массива в встроенный массив
Span<T>
должен быть доступен для записи. Если массив доступен для чтения, его нельзя преобразовать в записываемый объектSpan<T>
. Вместо этого можно использоватьReadOnlySpan<T>
. - Безопасный контекст встроенного массива должен быть по крайней мере таким же, как безопасный контекст
Span<T>
преобразования илиReadOnlySpan<T>
для успешного преобразования. Необходимо ограничить контекст диапазона или развернуть область встроенного массива.
Кроме того, компилятор никогда не создает вызовы Slice
метода в встроенном буфере. Операторы преобразования для преобразования встроенного буфера в или Span
ReadOnlySpan
не вызываются. Компилятор создает код для создания System.Span<T> или System.ReadOnlySpan<T> непосредственно из буфера памяти.