C#
case insensitive comparison
equals operator
programming
.NET

Is there a C case insensitive equals operator?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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

Related reading
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
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.