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

List<T>.IndexOf outputs incorrect error message #67423

Closed
HeinziAT opened this issue Apr 1, 2022 · 4 comments · Fixed by #67696
Closed

List<T>.IndexOf outputs incorrect error message #67423

HeinziAT opened this issue Apr 1, 2022 · 4 comments · Fixed by #67696
Labels
area-System.Collections enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@HeinziAT
Copy link

HeinziAT commented Apr 1, 2022

Description

The error message returned by List<T>.IndexOf if an invalid index is used is incorrect. As it is currently implemented, the size of the collection (2 in the repro example below) is a valid input for index.

Reproduction Steps

// list of length 2
var list = new List<string>() { "a", "b" };

Console.WriteLine(list.IndexOf("a", 2)); // yields -1
Console.WriteLine(list.IndexOf("a", 3)); // yields an error

(fiddle)

Expected behavior

An ArgumentException with the following error text is thrown:

Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'index')

(Alternatively: Must be non-negative and not greater than the size of the collection.)

Actual behavior

An ArgumentException with the following error text is thrown:

Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

Regression?

No response

Known Workarounds

No response

Configuration

Tested with dotnetfiddle, with all currently available compilers (.NET 4.7.2, Roslyn 4.0, .NET 6).

Other information

I do not suggest to change the behavior of IndexOf - the current behavior is the only sane and consistent one. However, the error message (and the documentation of List<T>.IndexOf) should be updated to reflect the actual behavior.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Collections untriaged New issue has not been triaged by the area owner labels Apr 1, 2022
@ghost
Copy link

ghost commented Apr 1, 2022

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

Issue Details

Description

The error message returned by List<T>.IndexOf if an invalid index is used is incorrect. As it is currently implemented, the size of the collection (2 in the repro example below) is a valid input for index.

Reproduction Steps

// list of length 2
var list = new List<string>() { "a", "b" };

Console.WriteLine(list.IndexOf("a", 2)); // yields -1
Console.WriteLine(list.IndexOf("a", 3)); // yields an error

(fiddle)

Expected behavior

An ArgumentException with the following error text is thrown:

Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'index')

(Alternatively: Must be non-negative and not greater than the size of the collection.)

Actual behavior

An ArgumentException with the following error text is thrown:

Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

Regression?

No response

Known Workarounds

No response

Configuration

Tested with dotnetfiddle, with all currently available compilers (.NET 4.7.2, Roslyn 4.0, .NET 6).

Other information

I do not suggest to change the behavior of IndexOf - the current behavior is the only sane and consistent one. However, the error message (and the documentation of List<T>.IndexOf) should be updated to reflect the actual behavior.

Author: HeinziAT
Assignees: -
Labels:

area-System.Collections, untriaged

Milestone: -

@B1Z0N
Copy link
Contributor

B1Z0N commented Apr 1, 2022

From what I see we are pretty much inconsistent in usage of ThrowHelper.ThrowArgumentOutOfRange_IndexException in corelib and other libraries. For example just on List in the same file see current IndexOf example and this indexer here.

ThrowHelper.ThrowArgumentOutOfRange_IndexException uses SR.ArgumentOutOfRange_Index internally. And that one in turn belongs to resource files like this one here. I think that perhaps we should just split it into two:

  • SR.ArgumentOutOfRange_IndexMustBeLessThan for errors like that in List indexer and other throw if index >= size cases
  • SR.ArgumentOutOfRange_IndexMustBeLessThanOrEqual for errors like current IndexOf and other throw if index > size cases

Of course we also should not forget to update docs.

I would be grateful if someone from area owners, perhaps @jeffhandley, answered:

  1. How is the idea, namings, backward compat problems, etc?
  2. I'd like to take the job as a contributor, may I?

@Clockwork-Muse
Copy link
Contributor

Naive guess: it's implemented this way to support striding/slicing:

int previousIndex = 0;
int index = commaDelimitedString.IndexOf(",", 0);

while(index > -1)
{
    handleElement(commaDelimitedString.Substring(previousIndex, index));
    previousIndex = index;
    index = commaDelimitedString.IndexOf(",", index + 1);
}

...also, consider the case when the string is empty.

@eiriktsarpalis
Copy link
Member

@B1Z0N happy to accept a PR that improves this.

@eiriktsarpalis eiriktsarpalis added enhancement Product code improvement that does NOT require public API changes/additions and removed untriaged New issue has not been triaged by the area owner labels Apr 5, 2022
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Apr 5, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 7, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 8, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 8, 2022
B1Z0N added a commit to B1Z0N/runtime that referenced this issue Apr 8, 2022
Separated "Must be less than the size" and "Must be less than or equal to the size" error messages.
Now first one goes in "throw on index >= size case" and the second goes in "throw on index > size".

Fix dotnet#67423
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 13, 2022
@ghost ghost locked as resolved and limited conversation to collaborators May 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Collections enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants