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:
string a = "cat";
string b = "CAT".ToLower();
Console.WriteLine(a == b); // True
Console.WriteLine(a == "Cat"); // False
Console.WriteLine(a != "dog"); // TrueLet's go through the example line by line:
"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.a == bcompares them character by character and printsTrue.a == "Cat"printsFalse:'c'and'C'are different characters, and letter case matters.!=gives the opposite answer:"cat"is not equal to"dog", so it printsTrue.
== 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:
string answer = "YES";
Console.WriteLine(answer == "yes"); // False
Console.WriteLine(answer.Equals("yes", StringComparison.OrdinalIgnoreCase)); // TrueStringComparison.OrdinalIgnoreCase
The name of the way to compare has two parts:
Ordinalmeans comparing character with character as they are, without the rules of any language;IgnoreCasemeans 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
ToLowercreates a new string, although all you need is the answertrueorfalse; ToLowerandToUpperfollow the computer's regional settings. With Turkish settings,"TITLE".ToLower()gives"tıtle"with a dotless letterı, and the comparison with"title"returnsfalse.
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:
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)); // TrueCommon mistake
Someone tried to compare strings in alphabetical order with <:
string a = "apple";
string b = "banana";
Console.WriteLine(a < b); // ✗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
acomes beforebin alphabetical order; - zero for equal strings;
- a positive number if
acomes 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
EqualsandStringComparison.OrdinalIgnoreCase, not withToLower. string.IsNullOrEmptychecks for an empty string andnull, andstring.IsNullOrWhiteSpacealso for a string of spaces.<and>do not compile for strings; alphabetical order comes fromstring.Compare.