The C# string.Empty
field is an empty string
literal. It is not the same as an empty string
literal constant—there is a subtle difference.
We compare ways to create, and test, empty strings. An understanding of string
literals is helpful here. There are some minor performance differences.
In this example we use string.Empty
in a C# program. The string.Empty
field is initialized to the empty string
literal at runtime by .NET.
string.Empty
cannot be used in a switch
. But we can test with string.Empty
in if
-statements.string.Empty
. This is mostly equivalent to "". We test the variable against the constant "", which returns true.Length
of the Empty string
. Its length is 0, so the string
Empty is printed.switch
statement on string.Empty
. We cannot use string.Empty
as a case, as it is not a constant.using System; // Part 1: initialize string to empty string field. string value = string.Empty; if (value == "") { Console.WriteLine("Empty"); } // Part 2: test against Length. if (value.Length == 0) { Console.WriteLine("Empty"); } // Part 3: switch on the string constant. // ... We cannot have string.Empty as a case. switch (value) { case "": { Console.WriteLine("Empty"); break; } }Empty Empty Empty
An important point is to focus on the intention of code. If we want to see if a string
has characters, IsNullOrEmpty
is a good choice.
string
has characters.IsNullOrEmpty
, code is easier to understand and less likely to have mistakes in the logic that cause the slow path to be run.using System; string animal = ""; if (!string.IsNullOrEmpty(animal)) { // Do something that might be slow. Console.WriteLine(animal.ToUpper()); } else { Console.WriteLine("SKIPPED"); }SKIPPED
string
An empty string
has 0 chars. These strings can be checked using a clear and efficient method. Using the fastest method can help many programs.
string
against the empty string
literal. If both strings are literals, this would be faster.string.IsNullOrEmpty
, and it has slightly different logic (it handles null
).Length
property. The Length
check throws a NullReferenceException
when the string
is null
.null
), using Length
is the fastest. This was last tested in .NET 7.using System; using System.Diagnostics; // Get empty string. string input = "a".Replace("a", ""); int count = 0; const int m = 100000000; // Version 1: test against empty literal. Stopwatch s1 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { if (input == "") { count++; } } s1.Stop(); // Version 2: use IsNullOrEmpty. Stopwatch s2 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { if (string.IsNullOrEmpty(input)) { count++; } } s2.Stop(); // Version 3: test Length. Stopwatch s3 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { if (input.Length == 0) { count++; } } s3.Stop(); Console.WriteLine(s1.ElapsedMilliseconds); Console.WriteLine(s2.ElapsedMilliseconds); Console.WriteLine(s3.ElapsedMilliseconds); 70 ms == "" 251 ms IsNullOrEmpty 33 ms Length == 0
string.Empty
When you specify "" instead string.Empty
, the C# compiler itself will know the value of the string
data. The runtime is not a part of this decision.
string.Empty
is much slower than "", by using a conditional that is removed by the C# compiler.string.Empty
read only field against the null
literal in a tight loop.string
literal against null
in a tight loop. The constant comparison can be removed at compile-time.string.Empty
.using System; using System.Diagnostics; const int _max = 100000000; var s1 = Stopwatch.StartNew(); // Version 1: test string.Empty. for (int i = 0; i < _max; i++) { if (string.Empty == null) { throw new Exception(); } } s1.Stop(); var s2 = Stopwatch.StartNew(); // Version 2: test string literal. for (int i = 0; i < _max; i++) { if ("" == null) { throw new Exception(); } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));0.57 ns string.Empty 0.28 ns ""
Here we look inside .NET and see how the Empty field is initialized. In the String
class
, look at the static
constructor.
string
literal instance.static String() { Empty = ""; // // More initialization omitted // }public static readonly string Empty;
Because string.Empty
is initialized in the static
constructor for the String
class
, it cannot be determined when you compile your program. It is a readonly
field.
const
strings. So string.Empty
, a readonly
field, cannot be used.switch
statements are implemented as a Dictionary
, providing constant lookup times.If you look at == in the IL, it is called op_Equality
. This operator compiles to a method call (like any other). The == is just syntactic sugar.
An empty string
can be checked in many ways. We choose which one depending on clarity and convention (what is used already). The string.Empty
field can be used.