C#
case insensitive comparison
equals operator
programming
.NET

Is there a C case insensitive equals operator?

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

C# does not have a case-insensitive equals operator. The == operator and string.Equals() are case-sensitive by default. For case-insensitive comparison, use string.Equals(a, b, StringComparison.OrdinalIgnoreCase) for the best combination of performance and correctness. For culture-aware comparisons (sorting, display), use StringComparison.CurrentCultureIgnoreCase. Avoid ToLower()/ToUpper() for comparison — they allocate new strings and have edge cases with certain Unicode characters.

csharp
1string a = "Hello";
2string b = "hello";
3
4// Case-insensitive comparison — preferred
5bool equal = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
6// true
7
8// Instance method version
9bool equal2 = a.Equals(b, StringComparison.OrdinalIgnoreCase);
10// true
11
12// Case-sensitive (default behavior)
13bool caseSensitive = (a == b);
14// false

StringComparison.OrdinalIgnoreCase performs a byte-level comparison after case folding, making it the fastest option for non-linguistic comparisons like file paths, identifiers, and configuration keys.

StringComparison Options

OptionUse CasePerformance
OrdinalIgnoreCaseIdentifiers, paths, keysFastest
CurrentCultureIgnoreCaseUser-facing text in current localeMedium
InvariantCultureIgnoreCaseCulture-independent linguistic comparisonMedium
csharp
1// Culture-aware comparison (for user-facing text)
2bool result = string.Equals("straße", "STRASSE",
3    StringComparison.CurrentCultureIgnoreCase);
4// Result depends on culture — true in German culture
5
6// Ordinal comparison (byte-level, culture-independent)
7bool result2 = string.Equals("straße", "STRASSE",
8    StringComparison.OrdinalIgnoreCase);
9// false — ordinal does not handle special case folding rules

Common Patterns

Switch Statement (C# 7+)

csharp
1string command = "QUIT";
2
3// Pattern matching with case-insensitive check
4if (command.Equals("quit", StringComparison.OrdinalIgnoreCase))
5{
6    Console.WriteLine("Exiting...");
7}

Contains, StartsWith, EndsWith

csharp
1string text = "Hello World";
2
3bool contains = text.Contains("hello", StringComparison.OrdinalIgnoreCase);
4// true
5
6bool startsWith = text.StartsWith("HELLO", StringComparison.OrdinalIgnoreCase);
7// true
8
9bool endsWith = text.EndsWith("WORLD", StringComparison.OrdinalIgnoreCase);
10// true

Dictionary with Case-Insensitive Keys

csharp
1var dict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
2{
3    ["Apple"] = 1,
4    ["Banana"] = 2
5};
6
7Console.WriteLine(dict["apple"]);   // 1
8Console.WriteLine(dict["BANANA"]);  // 2
9Console.WriteLine(dict.ContainsKey("APPLE")); // true

LINQ Queries

csharp
1var names = new List<string> { "Alice", "Bob", "ALICE", "charlie" };
2
3var matches = names
4    .Where(n => n.Equals("alice", StringComparison.OrdinalIgnoreCase))
5    .ToList();
6// ["Alice", "ALICE"]
7
8var distinct = names
9    .Distinct(StringComparer.OrdinalIgnoreCase)
10    .ToList();
11// ["Alice", "Bob", "charlie"]

HashSet with Case-Insensitive Comparison

csharp
1var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
2{
3    "Apple", "Banana"
4};
5
6Console.WriteLine(set.Contains("apple"));  // true
7Console.WriteLine(set.Add("APPLE"));       // false — already exists

Why Not ToLower() or ToUpper()

csharp
1// BAD — allocates new strings, has Unicode edge cases
2bool equal = a.ToLower() == b.ToLower();
3
4// GOOD — no allocation, correct for all cases
5bool equal = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

ToLower() and ToUpper() create new string objects on every call, which matters in loops or hot paths. They also have the "Turkish I" problem — in Turkish culture, 'I'.ToLower() produces 'ı' (dotless i), not 'i'.

String.Compare for Ordering

csharp
1int result = string.Compare("apple", "BANANA", StringComparison.OrdinalIgnoreCase);
2// Negative — "apple" comes before "BANANA"
3
4// Sort a list case-insensitively
5var fruits = new List<string> { "Banana", "apple", "Cherry" };
6fruits.Sort(StringComparer.OrdinalIgnoreCase);
7// ["apple", "Banana", "Cherry"]

Common Pitfalls

  • Using ToLower() or ToUpper() for comparison instead of StringComparison: This allocates a new string on every comparison and fails with the Turkish I problem. string.Equals(a, b, StringComparison.OrdinalIgnoreCase) is faster and correct across all cultures.
  • Forgetting that == is always case-sensitive: There is no way to make the == operator case-insensitive in C#. You must use string.Equals() with a StringComparison parameter or use StringComparer for collections.
  • Using InvariantCultureIgnoreCase when OrdinalIgnoreCase suffices: InvariantCulture is slower because it applies linguistic rules. For non-linguistic comparisons (identifiers, paths, keys), OrdinalIgnoreCase is both faster and more predictable.
  • Creating a Dictionary without StringComparer and then doing case-insensitive lookups: Without passing StringComparer.OrdinalIgnoreCase to the constructor, dictionary keys are case-sensitive. Manually calling ToLower() on keys is error-prone and slower.
  • Assuming Contains() without a StringComparison parameter is case-insensitive: The parameterless string.Contains(string) is case-sensitive in .NET. The overload accepting StringComparison was added in .NET Core 2.1. On .NET Framework, use IndexOf with StringComparison instead.

Summary

  • C# has no case-insensitive == operator — use string.Equals(a, b, StringComparison.OrdinalIgnoreCase)
  • Use StringComparison.OrdinalIgnoreCase for identifiers, paths, and configuration keys
  • Use StringComparison.CurrentCultureIgnoreCase for user-facing text comparison
  • Pass StringComparer.OrdinalIgnoreCase to Dictionary, HashSet, and LINQ methods
  • Avoid ToLower()/ToUpper() for comparisons — they allocate strings and have Unicode edge cases

Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms