-
Couldn't load subscription status.
- Fork 5.2k
Description
Background and motivation
string.StartsWith(char) and string.EndsWith(char) are useful shortcuts for this.Length > 0 && this[0] == 'a'.
They also sometimes save you from having to declare temporary locals SomeCall().StartsWith('a').
For strings, they are also more efficient now but that's not the main motivation and likely wouldn't apply to Span extensions.
The fact that Span is missing such a helper feels like an oversight on an otherwise helpful API surface of utility extensions and I often end up writing a helper class that polyfills these. A quick GH search shows ~10 other such places.
It also means that some analyzers light up on string, but not on ReadOnlySpan<char>, e.g. the recently added CA1858 - "Use StartsWith instead of IndexOf".
I didn't find an existing issue for these so figured they're at least worth discussing.
At least unlike most? other extensions (e.g. IndexOf, StartsWith(ReadOnlySpan, ReadOnlySpan) ...), these methods are trivial to polyfill without losing out on potential perf.
Edit: more discussion around these APIs also at #85374
API Proposal
namespace System;
public static class MemoryExtensions
{
// Existing
public static bool StartsWith(this System.ReadOnlySpan<char> span, System.ReadOnlySpan<char> value, System.StringComparison comparisonType);
public static bool StartsWith<T>(this System.ReadOnlySpan<T> span, System.ReadOnlySpan<T> value) where T : System.IEquatable<T>?;
public static bool StartsWith<T>(this System.Span<T> span, System.ReadOnlySpan<T> value) where T : System.IEquatable<T>?;
// ... same pattern for EndsWith
// Proposed
public static bool StartsWith<T>(this System.ReadOnlySpan<T> span, T value) where T : System.IEquatable<T>?;
public static bool StartsWith<T>(this System.Span<T> span, T value) where T : System.IEquatable<T>?;
public static bool EndsWith<T>(this System.ReadOnlySpan<T> span, T value) where T : System.IEquatable<T>?;
public static bool EndsWith<T>(this System.Span<T> span, T value) where T : System.IEquatable<T>?;
}API Usage
-static bool IsNameHidden(ReadOnlySpan<char> fileName) => fileName.Length > 0 && fileName[0] == '.';
+static bool IsNameHidden(ReadOnlySpan<char> fileName) => fileName.StartsWith('.');Alternative Designs
While most helpers on MemoryExtensions are available for both Span and ReadOnlySpan of any T, the vast majority of use for this one will likely end up being ReadOnlySpan<char>.
public static bool StartsWith(this System.ReadOnlySpan<char> span, char value);
public static bool EndsWith(this System.ReadOnlySpan<char> span, char value);Risks
No response