-
-
Notifications
You must be signed in to change notification settings - Fork 64
Closed
Description
- Rule: MA0112 - Use 'Count > 0' instead of 'Any()'
- Built-in Equivalent: CA1860 - Avoid using 'Enumerable.Any()' extension method
Analysis
MA0112 and CA1860 serve the same purpose: optimizing collection checks by using Count > 0 or Length > 0 instead of Any() when the collection has an efficient count/length property, providing better performance.
MA0112 Coverage
- Detects inefficient use of Any() on collections with Count/Length
- Promotes performance optimization in collection checks
- Suggests using direct count comparisons
CA1860 Coverage
- Detects unnecessary use of Enumerable.Any() extension method
- Official Microsoft rule for collection performance optimization
- Recommends Count/Length properties when available
- Part of the .NET performance guidelines
Code Examples
Problematic code detected by both rules:
// Both MA0112 and CA1860 will flag these
public class DataProcessor
{
public bool ProcessData(List<string> items, string[] array, ICollection<int> collection)
{
// Inefficient - List<T> has Count property!
if (items.Any())
{
return true;
}
// Inefficient - arrays have Length property!
if (array.Any())
{
return true;
}
// Inefficient - ICollection<T> has Count property!
if (collection.Any())
{
return true;
}
return false;
}
}Recommended fix:
// Both rules suggest using Count/Length properties
public class DataProcessor
{
public bool ProcessData(List<string> items, string[] array, ICollection<int> collection)
{
// Efficient - direct Count access!
if (items.Count > 0)
{
return true;
}
// Efficient - direct Length access!
if (array.Length > 0)
{
return true;
}
// Efficient - direct Count access!
if (collection.Count > 0)
{
return true;
}
return false;
}
}Performance Comparison
// Performance test scenarios
var list = new List<int>(Enumerable.Range(1, 1000));
// Slow: O(1) but with method call overhead and iterator creation
bool hasItemsSlow = list.Any();
// Fast: O(1) direct property access
bool hasItemsFast = list.Count > 0;
// For IEnumerable<T> without Count, Any() is still appropriate
IEnumerable<int> enumerable = list.Where(x => x > 500);
bool hasFiltered = enumerable.Any(); // Correct - no efficient Count availableWhen to Use Each Approach
Use Count/Length > 0 when:
List<T>,Array,ICollection<T>,IReadOnlyCollection<T>- Any collection with O(1) Count/Length property
- Performance is critical
Use Any() when:
IEnumerable<T>without known collection type- Filtered sequences (Where, Select, etc.)
- Lazy evaluation is desired
Collections with Efficient Count
// These have O(1) Count/Length - prefer over Any()
List<T> list; // list.Count > 0
T[] array; // array.Length > 0
Dictionary<K,V> dict; // dict.Count > 0
HashSet<T> set; // set.Count > 0
Queue<T> queue; // queue.Count > 0
Stack<T> stack; // stack.Count > 0
ICollection<T> coll; // coll.Count > 0Recommendation
CA1860 is the official Microsoft analyzer rule that provides equivalent functionality to MA0112. Since both rules target the same collection performance optimization and CA1860 is the standard rule for LINQ performance, MA0112 should be deprecated in favor of CA1860.
Migration Path
- Enable CA1860 in your analyzer configuration:
<WarningsAsErrors Include="CA1860" />
- Disable MA0112:
<WarningsNotAsErrors Include="MA0112" />
- Update any rule suppressions from MA0112 to CA1860
Related
- Parent issue: Consider deprecating rules that are now covered by built-in .NET analyzers #835 - Consider deprecating rules that are now covered by built-in .NET analyzers
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels