Cause
When using a range-indexer on an array and implicitly assigning the value to System.Span or System.Memory.
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.Span or System.Memory 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:
Span<SomeT> slice = arr[a..b];Memory<SomeT> slice = arr[a..b];
Does not detect
Explicit conversions:
Span<SomeT> slice = (Span<SomeT>)arr[a..b];Memory<SomeT> slice = (Memory<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.
class C
{
public void TestMethod(byte[] arr)
{
// The violation occurs for both statements below
Span<byte> tmp2 = arr[0..5];
Memory<byte> tmp4 = arr[5..10];
...
}
}class C
{
public void TestMethod(byte[] arr)
{
// The violations fixed with AsSpan or AsMemory accordingly
Span<byte> tmp2 = arr.AsSpan()[0..5];
Memory<byte> tmp4 = arr.AsMemory()[5..10];
...
}
}You can also avoid this warning by adding an explicit cast.
class C
{
public void TestMethod(byte[] arr)
{
// The violation occurs
Span<byte> tmp1 = arr[0..5];
Memory<byte> tmp2 = arr[5..10];
...
}
}class C
{
public void TestMethod(byte[] arr)
{
// The violation fixed with explicit casting
Span<byte> tmp1 = (Span<byte>)arr[0..5];
Memory<byte> tmp2 = (Memory<byte>)arr[5..10];
...
}
}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.
#pragma warning disable CA1833
// The code that's violating the rule is on this line.
#pragma warning restore CA1833To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA1833.severity = noneFor more information, see How to suppress code analysis warnings.
Related rules
- CA1831: Use AsSpan instead of Range-based indexers for string when appropriate
- CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array