Skip to content

MemoryExtensions.AsSpan/AsMemory throws different exception than {ReadOnly}Span.Slice #53622

@gfoidl

Description

@gfoidl

In

public static ReadOnlySpan<char> AsSpan(this string? text, int start, int length)
{
if (text == null)
{
if (start != 0 || length != 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
return default;
}
#if TARGET_64BIT
// See comment in Span<T>.Slice for how this works.
if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)text.Length)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
#else
if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
#endif
return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), (nint)(uint)start /* force zero-extension */), length);
}

ExceptionArgument.start is used, but length may be the faulty argument.

public ReadOnlySpan<T> Slice(int start, int length)
{
#if TARGET_64BIT
// See comment in Span<T>.Slice for how this works.
if ((ulong)(uint)start + (ulong)(uint)length > (ulong)(uint)_length)
ThrowHelper.ThrowArgumentOutOfRangeException();
#else
if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
ThrowHelper.ThrowArgumentOutOfRangeException();
#endif
return new ReadOnlySpan<T>(ref Unsafe.Add(ref _pointer.Value, (nint)(uint)start /* force zero-extension */), length);
}

only throws ArgumentOutOfRangeException without specifying the paramname.
{RO}S ctor does it the same way.

Similar for AsMemory(this string? text, int start, int length);.

Should the behavior of MemoryExtensions.AsSpan/AsMemory be aligned to the one of Slice?

For reference see also #53463 (comment)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions