-
Notifications
You must be signed in to change notification settings - Fork 5k
Removes the outer loop for CountBy #106111
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
Changes from all commits
7b103f2
1d03872
ce61749
20edf2f
82212e0
7fa751b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -32,29 +32,29 @@ public void CountBy_SourceThrowsOnGetEnumerator() | |||||
{ | ||||||
IEnumerable<int> source = new ThrowsOnGetEnumerator(); | ||||||
|
||||||
var enumerator = source.CountBy(x => x).GetEnumerator(); | ||||||
var countBy = source.CountBy(x => x); | ||||||
|
||||||
Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext()); | ||||||
Assert.Throws<InvalidOperationException>(() => countBy.GetEnumerator().MoveNext()); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing you meant to assert this?
Suggested change
I don't think this is an acceptable behavioural change. Generally speaking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I know, in the Therefore, I think that the I think that the work can be done both as in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not an apples-to-apples comparison. IQueryable<int> queryable = new ThrowingGetEnumerator().AsQueryable()
.Select(x => x + 1)
.Where(x => x > 0);
IEnumerator<int> enumerator = queryable.GetEnumerator(); // No exception
enumerator.MoveNext(); // Exception
public class ThrowingGetEnumerator : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator() => throw new NotSupportedException();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
I strongly disagree that that it's an implementation detail. Changing the behavior can break user code that depends on this method not enumerating the source or throwing exceptions; it might not be important if you just foreach over the result, but it is in code that explicitly handles enumerators in bespoke ways. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would argue that this indicates an issue with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess |
||||||
} | ||||||
|
||||||
[Fact] | ||||||
public void CountBy_SourceThrowsOnMoveNext() | ||||||
{ | ||||||
IEnumerable<int> source = new ThrowsOnMoveNext(); | ||||||
|
||||||
var enumerator = source.CountBy(x => x).GetEnumerator(); | ||||||
var countBy = source.CountBy(x => x); | ||||||
|
||||||
Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext()); | ||||||
Assert.Throws<InvalidOperationException>(() => countBy.GetEnumerator().MoveNext()); | ||||||
} | ||||||
|
||||||
[Fact] | ||||||
public void CountBy_SourceThrowsOnCurrent() | ||||||
{ | ||||||
IEnumerable<int> source = new ThrowsOnCurrentEnumerator(); | ||||||
|
||||||
var enumerator = source.CountBy(x => x).GetEnumerator(); | ||||||
var countBy = source.CountBy(x => x); | ||||||
|
||||||
Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext()); | ||||||
Assert.Throws<InvalidOperationException>(() => countBy.GetEnumerator().MoveNext()); | ||||||
} | ||||||
|
||||||
[Fact] | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One issue I'm finding with this approach is that this is returning an enumerator whose implementation is public. Couldn't this result users taking a dependency on that implementation details which might prevent us from evolving the method in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A dictionary enumerator does not have any useful method or property, and a dictionary enumerator is hidden by the IEnumerator interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow, wouldn't this cast work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it will work. But
Dictionary.Enumerator
does not have any specific method or property.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the implementation to not use dictionary would result in this cast failing for anybody who might depend on this. This is why we never return enumerable/enumerator implementations that are public unless they are specifically present in the type signature of the method (as is the case with
ToList()
or the inner array inChunk()
).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't seen a code analyzer that would check this rule, I doubt it is so, why isn't there a code analyzer for this rule?