C#idiomatic C#
ca1832fundamentals/code-analysis/quality-rules

Code analysis

CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array

Learn about code analysis rule CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array

CA1832 Performance enabled by default in .NET 10: As suggestion
Fix is breaking or non-breaking Non-breakingApplicable languages C# and Visual Basic

Cause

When using a range-indexer on an array and implicitly assigning the value to System.ReadOnlySpan or System.ReadOnlyMemory.

Rule description

The range indexer on a System.Span is a non-copying System.Span.Slice operation. But for the range indexer on an array, the method System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray will be used instead of System.Span.Slice, which produces a copy of the requested portion of the array. This copy is usually unnecessary when it's implicitly used as a System.ReadOnlySpan or System.ReadOnlyMemory value. If a copy isn't intended, use the System.MemoryExtensions.AsSpan or System.MemoryExtensions.AsMemory method to avoid the unnecessary copy. If the copy is intended, either assign it to a local variable first or add an explicit cast.

The analyzer only reports when an implicit cast is used on the result of the range indexer operation.

Detects

Implicit conversions:

  • ReadOnlySpan<SomeT> slice = arr[a..b];
  • ReadOnlyMemory<SomeT> slice = arr[a..b];

Does not detect

Explicit conversions:

  • ReadOnlySpan<SomeT> slice = (ReadOnlySpan<SomeT>)arr[a..b];
  • ReadOnlyMemory<SomeT> slice = (ReadOnlyMemory<SomeT>)arr[a..b];

How to fix violations

To fix a violation of this rule, use the System.MemoryExtensions.AsSpan or System.MemoryExtensions.AsMemory extension method to avoid creating unnecessary data copies.

csharp
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs for both statements below
        ReadOnlySpan<byte> tmp1 = arr[0..2];
        ReadOnlyMemory<byte> tmp3 = arr[5..8];
        ...
    }
}
csharp
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violations fixed with AsSpan or AsMemory accordingly
        ReadOnlySpan<byte> tmp1 = arr.AsSpan()[0..2];
        ReadOnlyMemory<byte> tmp3 = arr.AsMemory()[5..8];
        ...
    }
}

You can also avoid this warning by adding an explicit cast.

csharp
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs
        ReadOnlySpan<byte> tmp1 = arr[0..2];
        ReadOnlyMemory<byte> tmp3 = arr[5..8];
        ...
    }
}
csharp
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation fixed with explicit casting
        ReadOnlySpan<byte> tmp1 = (ReadOnlySpan<byte>)arr[0..2];
        ReadOnlyMemory<byte> tmp3 = (ReadOnlyMemory<byte>)arr[5..8];
        ...
    }
}

When to suppress warnings

It's safe to suppress a violation of this rule if creating a copy is intended.

Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

csharp
#pragma warning disable CA1832
// The code that's violating the rule is on this line.
#pragma warning restore CA1832

To disable the rule for a file, folder, or project, set its severity to none in the configuration file.

ini
[*.{cs,vb}]
dotnet_diagnostic.CA1832.severity = none

For more information, see How to suppress code analysis warnings.

See also