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
Exclude Enumerable.Count<TSource>(IEnumerable<TSource>) #2774
Exclude Enumerable.Count<TSource>(IEnumerable<TSource>) #2774
Conversation
Can you clarify the exact analyzer change here? |
/// <item><term><c> 1 > enumerable.Count() </c></term><description><c> !enumerable.Any() </c></description></item> | ||
/// <item><term><c> 1 <= enumerable.Count() </c></term><description><c> enumerable.Any() </c></description></item> | ||
/// <item><term><c> enumerable.Count().Equals(0) </c></term><description><c> !enumerable.Any() </c></description></item> | ||
/// <item><term><c> 0.Equals(enumerable.Count()) </c></term><description><c> !enumerable.Any() </c></description></item> |
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 would prefer to keep all of these
The change is to exclude Only this method. The overload with a predicate and all other applicable methods from the other extensions are still being targeted. The difference between the C# and VB extension method invocation operations required to split the analyzer into language specific versions. |
@paulomorgado I think there is some miscommunication here. I agree with @sharwell that we should not remove
I don't think we should completely exclude |
I'm getting confused over all this. My understanding of @stephentoub's comments around all this is a run time issue. With this change, if you can for sure know at compile time that If you cannot determine at compile time that For example, if someone uses The benchmarks on dotnet/corefx#40377 show that the new version (as you said, @mavasani, only for .NET 5.0) is equal or better on allocations but it performs worst in 6 out of 9 use cases. And that's a comparison between new and old Is my understanding correct, @stephentoub? On a side note, |
Worse in the sense of additional allocation, but you lose out on a a diagnostic that can improve your code go from O(n) operation to O(1). As @sharwell mentioned, the latter is much more valuable for majority of programmers. Additionally, the allocation concern in Any() is addressed in newer versions of netcore after stephen's fix.
|
This should already be flagged by CA1829. What I'm going to add to CA1829, is the same for I don't have metrics to know if This is, at this point, mostly a conceptual/decision making discussion as, in one analyzer or the other, the code is all done. But I think it's a discussion worth having. |
void M(List<T> list, IEnumerable<T> enumerable)
{
if (list.Count() != 0) // This should only flag CA1829 - use property named Count
{ }
if (enumerable.Count() != 0) // This should flag CA1827 - use Any()
{ }
} This PR removes the CA1827 from the 2nd case above, which according to me makes this rule confusing and lose much of its value. I agree with Sam that we should not keep altering the rule based on API implementation details (which are likely to change again in future), when the drawback is just an additional allocation on certain code paths and that too has been fixed now.
Yes, that is correct. I am going to mark this PR as blocked until we conclude that the change in this PR is desirable. |
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.
As per the review comments
On .NET Core post-3.0. it will not be "fixed" on .NET Framework, nor backported to NET Core 3.0. |
I think that is totally acceptable. |
Manish and I disagree with Stephen's qualified objection to certain cases of this rule based on runtime behavior. We don't disagree with the arguments themselves (it's easy to prove they are correct in certain constructed scenarios), but rather disagree on whether those arguments are strong enough to impact the way this rule would be used in the majority of real-world applications. Even if this rule only ran on .NET Framework and no changes were ever made to the runtime behavior, we would want the rule to keep its original form. |
@paulomorgado - can you please provide a link to @stephentoub 's comments that you are referring to? |
Sorry @udlose. It was a private talk. |
Solves dotnet/roslyn#37959