I have written a piece of optimized code that contains special cases for null
and empty strings. I am now trying to write a unit test for this code. In order to do that, I need two empty (zero-length) string objects that are different objects. Like this:
string s1, s2;
Assert.IsTrue(s1.Length == 0 && s2.Length == 0);
Assert.IsTrue(!ReferenceEquals(s1, s2));
It turns out that most .NET Framework APIs string are checking for an empty result. They are returning string.Empty
in all those cases. For example, "x".Remove(0, 1)
returns string.Empty
.
How can I create fresh zero-length string objects?
There is no true 100% supported way of manufacturing a fresh zero-length string in .NET. As an implementation detail, existing string APIs may try to normalize zero-length return values to the instance string.Empty
, but whether or not they do this consistently isn't something a developer should be relying on.
In particular, the other two answers have problems:
The string.Copy
solution even includes the caveat that the method is obsolete in .NET Core 3.0. The method is likely to be removed entirely from a future version of .NET Core, so any solution which relies on calling string.Copy
is going to break when the application eventually moves on to the new version of the runtime.
The FastAllocateString
solution takes a dependency on an undocumented, internal API within the runtime. Internal APIs aren't guaranteed to stick around between versions. In fact, we're planning major changes in the way strings behave in the next version of .NET, and that work will almost certainly affect this internal API.
So, to your particular question as to whether there's a reliable way to manufacture a fresh zero-length string instance, the answer is no.
If you want to special-case zero-length strings in your code, the best solution would be to use the pattern if (myString.Length == 0) { /* ... */ }
. The patterns if (myString == string.Empty) { /* ... */ }
and if (myString == "") { /* ... */ }
will also work, but their codegen won't be as optimized as the first proposal.
If you want to special-case null or empty strings, the best solution would be to use the existing string.IsNullOrEmpty
API. The implementation of this method changes from version to version to take advantage of whatever JIT optimizations are available at the time.
Source: I am one of the primary developers on the System.String class.
You can use the Obsolete method String.Copy
string s1 = "";
string s2 = String.Copy("");
Assert.IsTrue(s1.Length == 0 && s2.Length == 0);
Assert.IsTrue(!ReferenceEquals(s1, s2));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With