Skip to content

[Analyzer proposal]: Simplify calls to string.Substring and Memory/Span.Slice #68946

Description

@GrabYourPitchforks

Inspired by Steve's comment at #68937 (comment).

We should consider promoting usage of Substring/Slice(offset) over Substring/Slice(offset, length) for "slice to the end of the buffer" scenarios. In both cases it makes the code a little easier to read and is less error-prone since it doesn't require the caller to get the length check correct. And for Slice specifically, it will result in slightly better codegen.

// Detect these patterns
someString.Substring(expression, someString.Length - expression);
someMemory.Slice(expression, someMemory.Length - expression);
someSpan.Slice(expression, someSpan.Length - expression);

// And replace them with these:
someString.Substring(expression);
someMemory.Slice(expression);
someSpan.Slice(expression);

Any analyzer / fixer would need to be a little smart and ensure that evaluating neither this nor expression has side effects, otherwise changing the number of occurrences from 2 to 1 would result in an observable behavioral change. This means that we might not be able to trigger the analyzer / fixer if this or expression contains a property accessor, unless we can reason that the property accessor is a dumb field wrapper.

The prevalent patterns that I saw in #68937 were:

value.Substring(local, value.Length - local);
value.Substring(local1 + local2, value.Length - local1 - local2);
value.Substring(local1 + local2, value.Length - (local1 + local2));
value.Substring(field, value.Length - field);
value.Substring(field + const, value.Length - field - const);
value.Substring(field + const, value.Length - (field + const));

Suggested category: Maintainability
Suggested severity: Info

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Runtimecode-analyzerMarks an issue that suggests a Roslyn analyzercode-fixerMarks an issue that suggests a Roslyn code fixer

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions