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