空对空。您使用哪一个?

最近一位同事告诉我,在设置字符串变量时不要使用 string.Empty,而要使用 null,因为它会污染堆栈?

他说不行

但是做 string mystring=null;

这真的重要吗? 我知道字符串是一个对象,所以它有点意义。

我知道这是一个愚蠢的问题,但你的观点是什么?

73813 次浏览

null and Empty are very different, and I don't suggest arbitrarily switching between them. But neither has any extra "cost", since Empty is a single fixed reference (you can use it any number of times).

There is no "pollution" on the stack caused by a ldsfld - that concern is.... crazy. Loading a null is arguably marginally cheaper, but could cause null-reference exceptions if you aren't careful about checking the value.

Personally, I use neither... If I want an empty string I use "" - simple and obvious. Interning means this also has no per-usage overhead.


At the IL level, the difference here between "" and Empty is just ldstr vs ldsfld - but both give the same single interned string reference. Furthermore, in more recent .NET versions the JIT has direct interception of these, yielding the empty string reference without actually doing a static field lookup. Basically, there is exactly no reason to care either way, except readability. I just use "".

It doesn't 'pollute the stack', there's no technical reason but there is a big difference between setting a variable to a reference to an object (even if it's an empty string) and null. They are not the same thing and should be used in different ways.

null should be used to indicate the absence of data, string.Empty (or "") to indicate the presence of data, in fact some empty text. Is there a specific case where you're not sure what is the most appropriate?

Edit, added examples:

  • You might use string.Empty as the default postfix for a person's name (most people don't have PhD for example)

  • You might use null for a configuration option that wasn't specified in the config file. In this case, string.Empty would be used if the config option was present, but the desired configured value was an empty string.

FWIW, I found that mixing "" and String.Empty doesn't work:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"


var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

In particular, if you use $.trim to get the value of an empty DOM input field, then compare it to String.Empty, you get false. Not sure why that is, but there you go. I now just use "" everywhere for consistency.

They are different as others already answered.

static void Main(string[] args)
{
string s1 = null;
string s2 = string.Empty;
string s3 = "";
Console.WriteLine(s1 == s2);
Console.WriteLine(s1 == s3);
Console.WriteLine(s2 == s3);
}

Results:

  1. false - since null is different from string.empty
  2. false - since null is different from ""
  3. true - since "" is same as string.empty

The problem with managing empty string vs. null strings is becoming a problem when you need to either persist it into a flat file or transfer it through communications, So I find it might be useful for other who visit this page to give a nice solution to that particular problem.

For the purpose of saving strings into a file or communications:
you will probably want to convert the string into bytes.
a good practice I recommend is to add 2 segments of header bytes to your converted string.

segment 1 - meta info which is stored in 1 byte and describes the length of the the next segment.

segment 2 - holds the length of the string to be saved.

example:
string "abcd" - to simplify I'll convert it using ASCII encoder and will get {65,66,67,68}.
calculate segment 2 will yield 4 - so 4 bytes are the length of the converted string.
calculate segment 1 will yield 1 - as just 1 byte was used to hold the length information of the converted string information (which was 4, i.e. if it was 260 I would get 2)

The new stripe of bytes will now be {1,4,65,66,67,68} which can be saved to a file.

The benefit in respect to the subject is that if I had an empty string to save I would get from conversion an empty array of bytes in the length of 0 and after calculating the segments I will end up having {1,0} which can be saved and later on loaded and interpreted back into an empty string. On the other hand if I had null value in my string I would end up having just {0} as my byte array to save and again when loaded can be interpreted back to null.

There are more benefits such as knowing what the size to be loaded or accumulate if you jag multiple strings.

Back to the subject - it will.. well kind of pollute the stack as the same principals described are being used by any system to differentiate nulls from empty.. so yes string.Empty does take more memory than null, though I wouldn't call it pollution.. it just 1 more byte.

It's been answered to death, but null means no value, not initialized. string.Empty means "" (a blank string) as it is stated on MSDN.

The safest way to check for an empty or null string is using string.IsNullOrEmpty.