Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: ArgumentOutOfRangeException.ThrowIfNegativeOrGreaterThanOrEqual #82930

Closed
xtqqczze opened this issue Mar 3, 2023 · 9 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime

Comments

@xtqqczze
Copy link
Contributor

xtqqczze commented Mar 3, 2023

Background and motivation

For the common case of validating an index to a span, array, string, etc.

Can be implemented in one branch as (uint)value >= (uint)other as opposed to two branches with the following:

ArgumentOutOfRangeException.ThrowIfNegative(arrayIndex);
ArgumentOutOfRangeException.ThrowIfGreaterThan(arrayIndex, array.Length);

API Proposal

public class ArgumentOutOfRangeException : ArgumentException
{
  public static void ThrowIfNegativeOrGreaterThan<T>(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null)
    where T : INumberBase<T>
  public static void ThrowIfNegativeOrGreaterThanOrEqual<T>(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null)
    where T : INumberBase<T>
}

API Usage

  private T[] array
  public T this[int arrayIndex]
  {
    get
    {
      ArgumentOutOfRangeException.ThrowIfNegativeOrGreaterThanOrEqual(arrayIndex, array.Length);
      return array[arrayIndex];
    }
  }

Alternatives

  • The proposed API, but internal only.
  • The JIT could be taught to recognize a range check and convert into a single branch.
@xtqqczze xtqqczze added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Mar 3, 2023
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Mar 3, 2023
@xtqqczze xtqqczze changed the title [API Proposal]: [API Proposal]: ArgumentOutOfRangeException.ThrowIfNegativeOrGreaterThanOrEqual Mar 3, 2023
@skyoxZ
Copy link
Contributor

skyoxZ commented Mar 3, 2023

I think we don't need INumberBase<T>, int is enough. And the method name could be simplified to ThrowIfNotWholeNumberLessThan.

@ghost
Copy link

ghost commented Mar 3, 2023

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

For the common case of validating an index to a span, array, string, etc.

Can be implemented in one branch as (uint)value >= (uint)other as opposed to two branches with the following:

ArgumentOutOfRangeException.ThrowIfNegative(arrayIndex);
ArgumentOutOfRangeException.ThrowIfGreaterThan(arrayIndex, array.Length);

API Proposal

namespace System

public class ArgumentOutOfRangeException : ArgumentException
{
  public static void ThrowIfNegativeOrGreaterThan<T>(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null)
    where T : INumberBase<T>
  public static void ThrowIfNegativeOrGreaterThanOrEqual<T>(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null)
    where T : INumberBase<T>
}

API Usage

  private T[] array
  public T this[int arrayIndex]
  {
    get
    {
      ArgumentOutOfRangeException.ThrowIfNegativeOrGreaterThanOrEqual(arrayIndex, array.Length);
      return array[arrayIndex];
    }
  }

Alternatives

  • The proposed API, but internal only.
  • The JIT could be taught to recognize a range check and convert into a single branch.
Author: xtqqczze
Assignees: -
Labels:

api-suggestion, area-System.Runtime, untriaged

Milestone: -

@oliverA28legnA

This comment was marked as duplicate.

@tannergooding
Copy link
Member

ThrowIfNegativeOrGreaterThan is a verbose and not very "intuitive" name in my opinion. It's the kind of name that you have to stop and think about what it means.

In my own libraries, I use the name ThrowIfNotInBounds and ThrowIfNotInInsertBounds instead. In my case I take int length directly and assert that length is positive. Doing the same for a public API in the BCL is probably not possible, but taking a T[], Span<T>, and ReadOnlySpan<T> would be. We could then consider taking ICollection<T> to cover other cases, but I imagine the majority case would be covered by the first three.

@tannergooding tannergooding added needs-author-action An issue or pull request that requires more info or actions from the author. and removed untriaged New issue has not been triaged by the area owner labels Mar 23, 2023
@ghost
Copy link

ghost commented Mar 23, 2023

This issue has been marked needs-author-action and may be missing some important information.

@stephentoub
Copy link
Member

Doing the same for a public API in the BCL is probably not possible, but taking a T[], Span, and ReadOnlySpan would be. We could then consider taking ICollection to cover other cases, but I imagine the majority case would be covered by the first three.

Note that #77749 proposes a ThrowIfBufferTooSmall, which I left some comments on in #77749 (comment). I'd be concerned about taking an ICollection<T> that could lead to interface dispatch (though hopefully it could be eliminated by the JIT in some cases) in an API that's intended to be super cheap.

@ghost ghost added the no-recent-activity label Apr 20, 2023
@ghost
Copy link

ghost commented Apr 20, 2023

This issue has been automatically marked no-recent-activity because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity.

@ghost
Copy link

ghost commented May 4, 2023

This issue will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days.

@ghost ghost closed this as completed May 4, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Jun 3, 2023
@tannergooding tannergooding removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Jun 24, 2024
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Projects
None yet
Development

No branches or pull requests

6 participants