Skip to content
Theory · Strings · lesson 7 of 10

Comparing strings

Take two receipts from the same shop for the same purchase. They are two different slips of paper, but the same thing is printed on them. Are the receipts the same? It depends on the question: "is it one slip?" or "is it one text?".

For strings, C# answers the second question. The == operator compares the text, character by character, even when the strings are two different objects:

C#
string a = "cat";
string b = "CAT".ToLower();
Console.WriteLine(a == b);     // True
Console.WriteLine(a == "Cat"); // False
Console.WriteLine(a != "dog"); // True

Let's go through the example line by line:

  1. "CAT".ToLower() creates a new string "cat" while the program runs. Memory now holds two strings with the same text, like two slips with the same purchase.
  2. a == b compares them character by character and prints True.
  3. a == "Cat" prints False: 'c' and 'C' are different characters, and letter case matters.
  4. != gives the opposite answer: "cat" is not equal to "dog", so it prints True.

== compares text

For arrays, == checks whether it is the same array, and two arrays with the same elements are not equal. For strings, == works differently: it compares the length and then every character. So strings with the same text are equal, wherever they came from.

Here the picture with receipts is not exact. Two strings with the same text sometimes turn out to be one object: identical literals, as you have seen, are stored as one string. For == this does not matter; it compares the text either way.

Interviewers often ask this: what does == compare for strings? In C#, the text, even though string is a reference type. In Java, == on strings compares references, so the answer depends on the language.

Ignoring case

The user answered YES, and the program expects yes. In meaning the answers are the same, but == tells them apart. To compare without regard to case, a string has the Equals method with a second argument, the way to compare:

C#
string answer = "YES";
Console.WriteLine(answer == "yes"); // False
Console.WriteLine(answer.Equals("yes", StringComparison.OrdinalIgnoreCase)); // True

StringComparison.OrdinalIgnoreCase

The name of the way to compare has two parts:

  • Ordinal means comparing character with character as they are, without the rules of any language;
  • IgnoreCase means treating a capital and a small letter as the same.

You can pass the same way to compare to string.Equals(answer, "yes", StringComparison.OrdinalIgnoreCase) as well: there both strings go in as arguments.

Why not ToLower

You can bring both strings to small letters: answer.ToLower() == "yes". This works too, but the approach has two drawbacks:

  • each ToLower creates a new string, although all you need is the answer true or false;
  • ToLower and ToUpper follow the computer's regional settings. With Turkish settings, "TITLE".ToLower() gives "tıtle" with a dotless letter ı, and the comparison with "title" returns false.

OrdinalIgnoreCase does not depend on the settings and creates no new strings.

The empty string

The empty string "" is a string with no characters; its length is 0. You can check whether a string is empty with s == "" or with s.Length == 0. More often people write string.IsNullOrEmpty(s): this method returns true both for the empty string and for the value null, which means there is no string at all.

A space is a character too, so the string " " is not empty. If a string of spaces only should count as empty, there is string.IsNullOrWhiteSpace:

C#
string empty = "";
string space = " ";
Console.WriteLine(empty.Length);                     // 0
Console.WriteLine(string.IsNullOrEmpty(empty));      // True
Console.WriteLine(string.IsNullOrEmpty(space));      // False
Console.WriteLine(string.IsNullOrWhiteSpace(space)); // True

Common mistake

Someone tried to compare strings in alphabetical order with <:

C#
string a = "apple";
string b = "banana";
Console.WriteLine(a < b); // ✗
TEXT
error CS0019: Operator '<' cannot be applied to operands of type 'string' and 'string'

The program does not compile: the < and > operators work on numbers and characters, but not on strings. The order of strings comes from string.Compare(a, b). The method returns:

  • a negative number if a comes before b in alphabetical order;
  • zero for equal strings;
  • a positive number if a comes after.

Here string.Compare(a, b) < 0 gives true.

Key points

  • == and != compare the text of strings character by character and with regard to case, even if they are two different objects.
  • To ignore case, compare with Equals and StringComparison.OrdinalIgnoreCase, not with ToLower.
  • string.IsNullOrEmpty checks for an empty string and null, and string.IsNullOrWhiteSpace also for a string of spaces.
  • < and > do not compile for strings; alphabetical order comes from string.Compare.