Cause
A range-indexer is used on a string and the value is implicitly assigned to ReadOnlySpan<char>.
Rule description
This rule fires when you use a range-indexer on a string and assign it to a span type. The range indexer on a System.Span is a non-copying System.Span.Slice operation, but for the range indexer on a string, the method System.String.Substring will be used instead of System.Span.Slice. This produces a copy of the requested portion of the string. 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 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 conversion:
ReadOnlySpan<char> slice = str[a..b];
Does not detect
Explicit conversion:
ReadOnlySpan<char> slice = (ReadOnlySpan<char>)str[a..b];
How to fix violations
To fix a violation of this rule, use System.MemoryExtensions.AsSpan instead of the System.Range-based indexer on the string to avoid creating unnecessary data copies.
public void TestMethod(string str)
{
// The violation occurs
ReadOnlySpan<char> slice = str[1..3];
...
}public void TestMethod(string str)
{
// The violation fixed with AsSpan extension method
ReadOnlySpan<char> slice = str.AsSpan()[1..3];
...
}You can also add an explicit cast to avoid this warning.
public void TestMethod(string str)
{
// The violation occurs.
ReadOnlySpan<char> slice = str[1..3];
...
}public void TestMethod(string str)
{
// The violation avoided with explicit casting.
ReadOnlySpan<char> slice = (ReadOnlySpan<char>)str[1..3];
...
}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 CA1831
// The code that's violating the rule is on this line.
#pragma warning restore CA1831To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA1831.severity = noneTo disable this entire category of rules, set the severity for the category to none in the configuration file.
[*.{cs,vb}]
dotnet_analyzer_diagnostic.category-Performance.severity = noneFor more information, see How to suppress code analysis warnings.
Related rules
- CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array
- CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array