Caution with List.Contains()

Rule ND2302 .NET Framework Usage / System.Collections

Matches calls to List<T>.Contains(), an O(N) operation. For large lists or frequent calls, prefer System.Collections.Generic.HashSet<T> whose Contains() is constant time.

Not a rule: O(N) Contains() is usually not a mistake; this query just points out a potential performance pitfall.

CQLinq source

This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.

// <Name>Caution with List.Contains()</Name>
// <Id>ND2302:CautionWithListContains</Id>

// warnif count > 0  // This query is n ot a rule per default

let containsMethods = ThirdParty.Methods.WithFullNameIn(
   "System.Collections.Generic.List<T>.Contains(T)",
   "System.Collections.Generic.IList<T>.Contains(T)",
   "System.Collections.ArrayList.Contains(Object)")

from m in Application.Methods.UsingAny(containsMethods) 
select new {
   m,
   methodsCalled = m.MethodsCalled.Intersect(containsMethods),   
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Expl>
// The *{0}* calls the *{1}* that operate{1?s:} in *O(N)*
// which could potentially lead to performance degradation.
//</Expl>

//<Desc>
// Matches calls to *List<T>.Contains()*, an *O(N)* operation. For large
// lists or frequent calls, prefer *System.Collections.Generic.HashSet<T>*
// whose *Contains()* is constant time.
//
// Not a rule: *O(N) Contains()* is usually not a mistake; this query just
// points out a potential performance pitfall.
//</Desc>

.NET Framework Usage / System.Collections: all 4 items