Skip to content

[API Proposal]: Add ArgumentOutOfRangeException.ThrowIfZero() #68339

@AraHaan

Description

@AraHaan

Background and motivation

While ArgumentNullException has ThrowIfNull, there is no way to have it be followed by a call to ArgumentNullException.ThrowIfZeroLength(/* params here which are the same as ThrowIfNull. */) because it does not exist yet (I think it should exist for those who want to throw this exception when:

  • the user passes in an empty {ReadOnly}Span<T> (it has no length)
  • the user passes in an empty string (it has no length)
  • the user passes in an empty array, enumerable, or collection (it has no length)

API Proposal

namespace System
{
    public class ArgumentOutOfRangeException : ArgumentException
    {
        // object? used for now but function may instead need to be made to target only types that have an .Length property.
        public static void ThrowIfZero(int value, string paramName);

        // thrown when value is less than min or greater than max.
        public static void ThrowIfOutsideRange(int value, int min, int max, string paramName);
    }
}

API Usage

An example function could be:

public sealed partial class BlowFish
{
    // snip members.

    public static void XorBlock(Span<byte> block, Span<byte> iv)
    {
        ArgumentOutOfRangeException.ThrowIfZero(block, nameof(block));
        ArgumentOutOfRangeException.ThrowIfZero(iv, nameof(iv));
        XorBlock_private(block, iv);
    }

    public static void XorBlock(Stream block, byte[] iv)
    {
        ArgumentNullException.ThrowIfNull(block, nameof(block));
        ArgumentNullException.ThrowIfNull(iv, nameof(iv));
        if (block is MemoryStream ms)
        {
            // this calls the span overload.
            XorBlock(ms.GetBuffer(), iv);
        }
    }

    // snip members.
}

Alternative Designs

Instead of using object? to add multiple versions of the throw function that is for {ReadOnly}Span<T>, string, arrays, enumerables, or collections. However I think some other way of doing it to where it does not become generic or even have multiple overloads could be done.
There was an idea of using object but it would not work for ref structs like {ReadOnly}Span<T>.
Also it was in ArgumentNullException instead of ArgumentOutOfRangeException.

Risks

Minimal

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions