Skip to content

MA0112 - Use 'Count > 0' instead of 'Any()' is handled by CA1860 #859

@Meir017

Description

@Meir017
  • 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 available

When 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 > 0

Recommendation

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

  1. Enable CA1860 in your analyzer configuration:
    <WarningsAsErrors Include="CA1860" />
  2. Disable MA0112:
    <WarningsNotAsErrors Include="MA0112" />
  3. Update any rule suppressions from MA0112 to CA1860

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions