string.Empty vs null。您使用哪个?


84

最近有个同事在工作,告诉我不要string.Empty在设置字符串变量时使用null,而是在污染堆栈时使用?

他说不要

string myString=string.Empty; 但是做 string mystring=null;

真的有关系吗?我知道字符串是一个对象,因此它很有意义。

我知道这是一个愚蠢的问题,但是您怎么看?


1
我不完全确定为什么要这么做。。。您能以示例的方式提供更多的代码吗?
stusmith

没有代码。我让我的同事看一下我正在调试的东西,他说,作为一般规则,“不要使用string.empty”在堆栈上将其设置为null。个人我一直使用string.Empty因为它的发布时间应该是正确的选择,而不是“”。
user712923 2011年


我的意思是... string.Empty""null都是常量值,但是它们都非常“简单”,以至于我看不到为什么要为变量分配一个值。如果需要捕获out变量,为什么不使用string myString;
stusmith

8
如今,关于这样的主题的争论充其量是充斥着,这些争论不仅仅关注可读性和语义,也不关注荒谬的微观优化。在给定的上下文中使用任何一种手段都是正确的。(例如,如果您知道某人没有中间名,则使用String.Empty;如果您不知道某人是否具有中间名,则使用null)。然后,一旦您具有正确的含义,就以一种明显正确且易于维护的方式编写代码。
杰森

Answers:


110

null并且Empty有很大的不同,我不建议随意它们之间进行切换。但是,这两个都没有任何额外的“成本”,因为它Empty是一个固定的参考(您可以多次使用它)。

ldsfld不会在堆栈上造成任何“污染” -这种担忧是……疯狂的。加载一个null可以说是稍微便宜,但可能会导致空引用异常,如果你不认真检查值。

就个人而言,我都不使用...如果我想使用空字符串""-简单明了。实习意味着这没有每次使用的开销。


在IL级别,“”和Empty之间的区别只是ldstr与ldsfld-但两者都给出相同的单个内联字符串引用。此外,在较新的.NET版本中,JIT可以直接截获这些字符串,从而产生空字符串引用,而无需实际执行静态字段查找。基本上,除了可读性之外,完全没有理由不管这两种方式。我只使用“”。


5
@ user712923,如果他有任何具体的问题回来,我很想听听他们的意见
Marc Gravell

4
@Marc:ASAIK“”创建一个对象,其中的String.Empty不是..检查这个这个。它有一些做用绳子实习生池....
塔拉巴尼说


1
+1代表使用""而不是6倍长的样板代码。谁提倡这种废话?@Jalal布拉德·艾布拉姆斯(Brad Abrams)的发布已严重过时,如果编译器仍未优化这两个代码来实现相同功能,那么微软将感到羞耻!但是修复他们的工作不是我们的工作。实际上,我们不需要:在第二个链接中,Lasse(在注释中)比较了与任一变体进行比较的程序集输出:它们是相同的。
康拉德·鲁道夫

1
@Konrad:一个示例是连接常量字符串时发生的情况:字符串类使用内部缓冲池,因此在创建新字符串时,该类将检查该字符串是否已在缓冲池中,然后将其添加到缓冲池中。因此,当""它将搜索整个池以检查它是否已经存在时,使用这种方式时string.Empty;,它将使用该预定义值,并且搜索将不再存在。课堂上还公开了这种方法:string.Intern/IsInterned检查一下
Jalal Said

34

它不会“污染堆栈”,没有技术上的原因,但是将变量设置为对对象的引用(即使它是空字符串)与之间有很大的区别null。它们不是同一件事,应该以不同的方式使用。

null应该用来表示不存在数据,string.Empty(或"")来表示存在数据,实际上是一些空白文本。在特定情况下,您不确定最合适的是什么?

编辑,添加示例:

  • 您可以将其string.Empty用作人名的默认后缀(例如,大多数人没有博士学位)

  • 您可能会使用null未在配置文件中指定的配置选项。在这种情况下,string.Empty如果存在config选项,但将使用所需的配置值为空字符串,则将使用该选项。


我从来没有想过那样,我不得不承认。给你你刚才说的,你介意给我一个例子。我知道你的解释是自我解释,但仍然...谢谢
user712923 2011年

2
好吧,选择其中一个的唯一原因是基于您使用它的位置。即使用string.Empty""当您要使用空字符串并且null要指示没有数据时。您可以将string.Empty一个人的名字(例如,大多数人没有博士学位)用作默认的后缀-以及null在配置文件中未指定的配置选项。在第二种情况下,string.Empty如果存在config选项,但将使用所需的配置值为空字符串,则将使用该选项。
基琳·约翰斯通

@Kieren Johnstone,如果没有后缀名称,为什么不使用它null来表示“没有后缀”?
OfirD

8

它们与其他人已经回答的不同。

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:
 false     - since null is different from string.empty
 false     - since null is different from ""
 true      - since "" is same as string.empty

当您需要将空字符串保存为平面文件或通过通信进行传输时,管理空字符串和空字符串的问题已成为一个问题,因此我发现它对于其他访问此页面的人来说可能是有用的这个特殊的问题。

为了将字符串保存到文件或通信中,
您可能需要将字符串转换为字节。
我建议的一种好的做法是将2个标题字节段添加到转换后的字符串中。

段1-元信息,存储在1个字节中,描述下一个段的长度。

段2-保留要保存的字符串的长度。

示例:
字符串“ abcd”-为简化起见,我将使用ASCII编码器对其进行转换,并将得到{65,66,67,68}。
计算段2将产生4-因此4个字节是转换后的字符串的长度。
计算段1将产生1-因为仅使用1个字节来保存转换后的字符串信息的长度信息(即4,即如果为260,我将得到2)

现在,新的字节带将为{1,4,65,66,67,68},可以将其保存到文件中。

相对于该主题的好处是,如果我有一个空字符串要保存,我将从转换中得到一个长度为0的空字节数组,在计算完段之后,我最终将得到{1,0}保存并稍后加载并解释回一个空字符串。另一方面,如果我的字符串中有空值,我最终将只保存{0}作为字节数组,并且在加载时再次可以解释为空。

还有更多的好处,例如,知道混入多个字符串时要加载或累积的大小。

回到主题上-它会..那样会污染堆栈,因为任何系统都使用该相同的原理来区分空值与空值。所以是的string.Empty比空值占用更多的内存,尽管我不会称它为污染..它只是另外一个字节。


1

它已经死了,但是null表示没有值,没有初始化。string.Empty表示“”(空白字符串),如MSDN中所述。

检查空字符串或空字符串的最安全方法是使用string.IsNullOrEmpty。


-2

FWIW,我发现,混合""String.Empty不工作:

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"

特别是,如果$.trim用于获取空DOM输入字段的值,然后将其与进行比较String.Empty,则会得到false。不知道为什么会这样,但是您去了。我现在只""在各处使用以保持一致性。


1
是。这就是为什么我们都应该保持检查.Length==0或使用的习惯的原因.Compare()
赞洛克

14
这个问题询问的是C#而不是js
Cole Johnson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.