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

Add LINQ APIs for Index and Range (#28776) #47950

Closed
wants to merge 0 commits into from

Conversation

Dixin
Copy link
Contributor

@Dixin Dixin commented Feb 6, 2021

Add LINQ APIs for index and range:

  • Enumerable
    • ElementAt(Index)
    • ElementAtOrDefault(Index)
    • Take(Range)
  • Queryable
    • ElementAt(Index)
    • ElementAtOrDefault(Index)
    • Take(Range)

Close #28776.

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented Feb 6, 2021

Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.

Issue Details

Add LINQ APIs for index and range:

  • Enumerable
    • ElementAt(Index)
    • ElementAtOrDefault(Index)
    • Take(Range)
  • Queryable
    • ElementAt(Index)
    • ElementAtOrDefault(Index)
    • Take(Range)

Close #28776.

Author: Dixin
Assignees: -
Labels:

area-System.Linq, new-api-needs-documentation

Milestone: -

select x;

Assert.Equal(q.ElementAtOrDefault(3), q.ElementAtOrDefault(3));
var q = Repeat(_ => from x in new[] { 9999, 0, 888, -1, 66, -777, 1, 2, -12345 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious what the motivation for this method is. It took me a while to grasp but it seems to be creating 3 identical IEnumerable instances? Why would that be needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original unit test creates a source, then calls ElementAtOrDefault twice on the same source, and asserts the result.

I am keeping the consistency.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but for all intents and purposes the source enumerable in the test is immutable. We should not expect noticeable difference no matter how many times it has been enumerated. I would recommend keeping the tests as simple as possible (in this case and most other cases using the Repeat method, q can be enumerated as many times as needed. Assuming this were not the case, perhaps MemberData is preferable?

var en1 = iterator1 as IEnumerator<int>;
Assert.False(en1 != null && en1.MoveNext());

var iterator2 = NumberRangeGuaranteedNotCollectionType(0, 3).Take(2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this code duplicated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

var en1 = iterator1 as IEnumerator<int>;
Assert.False(en1 != null && en1.MoveNext());

var iterator2 = NumberRangeGuaranteedNotCollectionType(0, 3).ToList().Take(2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


var source = new DelegateIterator<int>(
moveNext: () => ++state <= sourceCount,
var source = Repeat(index => new DelegateIterator<int>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only test I could find where Repeat is really needed.

Nevertheless the test has too many moving parts and each section is applying different sets of assertions. I would recommend either breaking this up into separate unit tests or perhaps it might be possible to factor out some of the state management into a local method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored the code.

Copy link
Member

@eiriktsarpalis eiriktsarpalis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, pending some feedback in the test code.

@stephentoub
Copy link
Member

Did you intend to close this? Seemed almost ready to merge.

@Dixin
Copy link
Contributor Author

Dixin commented Feb 20, 2021

@stephentoub No. Something went wrong when I manipulate my local git repo and push. Can you please reopen it?

@stephentoub
Copy link
Member

GitHub won't let me. I think the branch must have gotten messed up. Can you open a new PR?

@Dixin
Copy link
Contributor Author

Dixin commented Feb 20, 2021

@stephentoub @eiriktsarpalis Please use PR #48559.

I think the branch must have gotten messed up.

Yes. I did git reset --hard xxx & git push -f on an incorrect branch with an incorrect hash code xxx. It caused GitHub to auto close this PR. Sorry for the inconvenience.

@stephentoub
Copy link
Member

No worries. Thanks.

@ghost ghost locked as resolved and limited conversation to collaborators Mar 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal (& implementation): LINQ APIs to enable C# 8.0 index and range for IEnumerable<T>
3 participants