Устранение ошибок и предупреждений с помощью встроенных объявлений массива

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

  • 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.
  • Поле одного экземпляра не является буфером фиксированного размера.
  • Поле одного экземпляра не включает requiredvolatileмодификаторы , или readonly модификаторы.
  • Удалите модификатор из объявления встроенного record массива.

Доступ к элементам

Доступ к элементам встроенного массива выполняется так же, как и к любому массиву. Компилятор выдает следующие ошибки из неправильного доступа к элементу:

  • CS9166: индекс находится за пределами границ встроенного массива
  • CS9172: к элементам встроенного типа массива можно обращаться только с одним аргументом, неявно преобразованным в int, System.Indexили System.Range.
  • CS9173: доступ к встроенному массиву может не иметь именованного описателя аргументов
  • CS9189: foreach оператор в встроенном массиве типов не поддерживается

Кроме того, компилятор выдает следующее предупреждение при объявлении индексатора:

  • CS9181: индексатор встроенных массивов не будет использоваться для выражения доступа к элементам.

Созданный код для встроенного буфера обращается к памяти буфера напрямую, обходя объявленные индексаторы. Встроенные массивы нельзя использовать с инструкцией foreach .

Аргумент индексатора должен быть следующим:

  • Один из трех типов: int, a System.Index или a System.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> непосредственно из буфера памяти.