How can I make Array.Contains case-insensitive on a string array?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Array.Contains on strings is case-sensitive by default because it uses the default equality comparer. If you need case-insensitive matching, the correct solution is choosing the right comparer explicitly rather than normalizing strings ad hoc everywhere. The best approach depends on whether you need one-off lookup, repeated lookup, or culture-aware matching.
Use LINQ With a String Comparer
For a simple one-off check, use Enumerable.Contains with a comparer.
StringComparer.OrdinalIgnoreCase is usually the right default for identifiers, codes, and protocol-style strings.
Why OrdinalIgnoreCase Is Usually Best
There are several comparison modes in .NET. The two common ones here are:
- '
StringComparer.OrdinalIgnoreCase' - '
StringComparer.CurrentCultureIgnoreCase'
Use OrdinalIgnoreCase when comparison is technical rather than linguistic. It is predictable and usually faster.
Use culture-aware comparison only when user-facing linguistic behavior actually matters.
Avoid Manual ToLower() and ToUpper()
A common workaround is normalizing both sides with ToLowerInvariant() or ToUpperInvariant(). That works, but it creates extra strings and spreads comparison policy across the codebase.
Less desirable approach:
Cleaner approach:
The comparer-based version is clearer and avoids unnecessary allocations.
Repeated Lookups: Use a HashSet<string>
If you need many case-insensitive lookups, convert the array into a HashSet<string> with the right comparer.
This is much better than repeatedly scanning the whole array if the lookup count is high.
Null Handling
If arrays can contain null, think about the intended behavior. StringComparer handles comparison cleanly, but your surrounding logic still needs to be explicit.
Do not assume null semantics are the same as empty string semantics.
Exact Method Choice Matters
There are two different Contains paths developers often confuse:
- '
Array.IndexOf' - LINQ
Enumerable.Contains
Array.IndexOf does not accept a comparer for strings in the same convenient way. If you need custom comparison semantics, LINQ is usually the more direct choice.
For more custom matching, Any works well:
This is especially useful when additional conditions are needed.
Pick the Right Comparison Rule for the Domain
If strings represent usernames, file extensions, configuration keys, or command names, OrdinalIgnoreCase is usually the safest option. If strings represent human-language text shown to users, evaluate whether culture-aware behavior is actually required.
Do not choose the comparison rule casually. Equality semantics are part of your data contract.
Common Pitfalls
One common mistake is using ToLower() everywhere instead of one explicit comparer-based rule. Another is using culture-aware comparison for non-linguistic identifiers, which can create surprising behavior. Developers also keep arrays for repeated lookups when a HashSet<string> would be more appropriate. Null values are frequently ignored until an edge case appears. Finally, teams often mix different comparison rules in different modules and get inconsistent behavior.
Summary
- '
Array.Containson strings is case-sensitive by default.' - Use LINQ
ContainswithStringComparer.OrdinalIgnoreCasefor one-off case-insensitive checks. - Prefer comparer-based logic over manual case normalization.
- Use
HashSet<string>with a comparer for repeated lookups. - Choose comparison semantics based on domain needs, not convenience.
- Keep null handling and string comparison policy explicit.
Related reading
- How can I manipulate an array to make the largest number?
- How can I match up permutations of a long list with a shorter list according to the length of the shorter list?
- How can I match up permutations of a long list with a shorter list according to the length of the shorter list?
- How can I measure thread stack depth?
- How can I multiply all items in a list together with Python?
- How can I partition split up, divide a list based on a condition?
- How can I pass a list as a command-line argument with argparse?
- How can I pass a list as a command-line argument with argparse?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.