Resolve errors and warnings with inline array declarations
This article covers the following compiler errors and warnings:
- CS9164: Cannot convert expression to
Span<T>
because it is not an assignable variable - CS9165: Cannot convert expression to
ReadOnlySpan<T>
because it may not be passed or returned by reference - CS9166: Index is outside the bounds of the inline array
- CS9167: Inline array length must be greater than 0.
- CS9168: Inline array struct must not have explicit layout.
- CS9169: Inline array struct must declare one and only one instance field which must not be a ref field.
- CS9172: Elements of an inline array type can be accessed only with a single argument implicitly convertible to
int
,System.Index
, orSystem.Range
. - CS9173: An inline array access may not have a named argument specifier
- CS9180: Inline array element field cannot be declared as required, readonly, volatile, or as a fixed size buffer.
- CS9181: Inline array indexer will not be used for element access expression.
- CS9182: Inline array 'Slice' method will not be used for element access expression.
- CS9183: Inline array conversion operator will not be used for conversion from expression of the declaring type.
- CS9184: 'Inline arrays' language feature is not supported for inline array types with element field which is either a '
ref
' field, or has type that is not valid as a type argument. - CS9189:
foreach
statement on an inline array of type is not supported
Inline array declaration
You declare inline arrays as a struct
type with a single field, and an attribute that specifies the length of the array. The compiler generates the following errors for invalid inline array declarations:
- CS9167: Inline array length must be greater than 0.
- CS9168: Inline array struct must not have explicit layout.
- CS9169: Inline array struct must declare one and only one instance field which must not be a ref field.
- CS9180: Inline array element field cannot be declared as required, readonly, volatile, or as a fixed size buffer.
- CS9184: 'Inline arrays' language feature is not supported for inline array types with element field which is either a '
ref
' field, or has type that is not valid as a type argument.
To fix these arrays, ensure the following are true:
- The argument to the System.Runtime.CompilerServices.InlineArrayAttribute is a positive integer.
- The enclosing
struct
doesn't specify any explicit layout. - The enclosing
struct
has a single instance field, and that instance field is not aref
field. - The single instance field is not a fixed size buffer.
- The single instance field doesn't include the
required
,volatile
, orreadonly
modifiers.
Element access
You access elements of an inline array in the same way as any array. The compiler emits the following errors from incorrect element access:
- CS9166: Index is outside the bounds of the inline array
- CS9172: Elements of an inline array type can be accessed only with a single argument implicitly convertible to
int
,System.Index
, orSystem.Range
. - CS9173: An inline array access may not have a named argument specifier
- CS9189:
foreach
statement on an inline array of type is not supported
In addition, the compiler issues the following warning when you declare an indexer:
- CS9181: Inline array indexer will not be used for element access expression.
The generated code for an inline buffer accesses the buffer memory directly, bypassing any declared indexers. Inline arrays can't be used with the foreach
statement.
The argument to the indexer must be:
- One of these three types:
int
, aSystem.Index
or aSystem.Range
. - Can't be a named argument. The compiler generates the element accessor. The parameter doesn't have a name, so you can't use named arguments.
- Is included in the bounds of the array. Like all .NET arrays, inline array element access is bounds-checked. The index must be within the bounds of the inline array.
Conversions to Span
You often use System.Span<T> or System.ReadOnlySpan<T> to work with inline arrays. The compiler generates the following errors for invalid conversions:
- CS9164: Cannot convert expression to
Span<T>
because it is not an assignable variable - CS9165: Cannot convert expression to
ReadOnlySpan<T>
because it may not be passed or returned by reference
The compiler generates code that directly accesses the memory for an inline buffer. Therefore, some members aren't ever called. The compiler generates the following warnings if you write one of the members that aren't ever called:
- CS9182: Inline array 'Slice' method will not be used for element access expression.
- CS9183: Inline array conversion operator will not be used for conversion from expression of the declaring type.
An inline array can be implicitly converted to a Span<T>
or ReadOnlySpan<T>
to pass an inline array to methods. The compiler enforces restrictions on those conversions:
- The inline array must be writable in order to convert an inline array to a
Span<T>
. If the array is readonly, you can't convert it to a writableSpan<T>
. You can useReadOnlySpan<T>
instead. - The safe context of the inline array must be at least as wide as the safe context of the
Span<T>
orReadOnlySpan<T>
for the conversion to succeed. You must either limit the context of the span, or expand the scope of the inline array.
In addition, the compiler never generates calls to a Slice
method in an inline buffer. Conversion operators to convert an inline buffer to a Span
or ReadOnlySpan
aren't called. The compiler generates code to create a System.Span<T> or System.ReadOnlySpan<T> directly from the memory buffer.