最近有个同事在工作,告诉我不要string.Empty
在设置字符串变量时使用null
,而是在污染堆栈时使用?
他说不要
string myString=string.Empty;
但是做 string mystring=null;
真的有关系吗?我知道字符串是一个对象,因此它很有意义。
我知道这是一个愚蠢的问题,但是您怎么看?
最近有个同事在工作,告诉我不要string.Empty
在设置字符串变量时使用null
,而是在污染堆栈时使用?
他说不要
string myString=string.Empty;
但是做 string mystring=null;
真的有关系吗?我知道字符串是一个对象,因此它很有意义。
我知道这是一个愚蠢的问题,但是您怎么看?
string.Empty
,""
和null
都是常量值,但是它们都非常“简单”,以至于我看不到为什么要为变量分配一个值。如果需要捕获out
变量,为什么不使用string myString;
?
String.Empty
;如果您不知道某人是否具有中间名,则使用null
)。然后,一旦您具有正确的含义,就以一种明显正确且易于维护的方式编写代码。
Answers:
null
并且Empty
有很大的不同,我不建议随意它们之间进行切换。但是,这两个都没有任何额外的“成本”,因为它Empty
是一个固定的参考(您可以多次使用它)。
ldsfld不会在堆栈上造成任何“污染” -这种担忧是……疯狂的。加载一个null
可以说是稍微便宜,但可能会导致空引用异常,如果你不认真检查值。
就个人而言,我都不使用...如果我想使用空字符串""
-简单明了。实习意味着这也没有每次使用的开销。
在IL级别,“”和Empty之间的区别只是ldstr与ldsfld-但两者都给出相同的单个内联字符串引用。此外,在较新的.NET版本中,JIT可以直接截获这些字符串,从而产生空字符串引用,而无需实际执行静态字段查找。基本上,除了可读性之外,完全没有理由不管这两种方式。我只使用“”。
""
而不是6倍长的样板代码。谁提倡这种废话?@Jalal布拉德·艾布拉姆斯(Brad Abrams)的发布已严重过时,如果编译器仍未优化这两个代码来实现相同功能,那么微软将感到羞耻!但是修复他们的工作不是我们的工作。实际上,我们不需要:在第二个链接中,Lasse(在注释中)比较了与任一变体进行比较的程序集输出:它们是相同的。
""
它将搜索整个池以检查它是否已经存在时,使用这种方式时string.Empty;
,它将使用该预定义值,并且搜索将不再存在。课堂上还公开了这种方法:string.Intern/IsInterned
检查一下
它不会“污染堆栈”,没有技术上的原因,但是将变量设置为对对象的引用(即使它是空字符串)与之间有很大的区别null
。它们不是同一件事,应该以不同的方式使用。
null
应该用来表示不存在数据,string.Empty
(或""
)来表示存在数据,实际上是一些空白文本。在特定情况下,您不确定最合适的是什么?
编辑,添加示例:
您可以将其string.Empty
用作人名的默认后缀(例如,大多数人没有博士学位)
您可能会使用null
未在配置文件中指定的配置选项。在这种情况下,string.Empty
如果存在config选项,但将使用所需的配置值为空字符串,则将使用该选项。
string.Empty
或""
当您要使用空字符串并且null
要指示没有数据时。您可以将string.Empty
一个人的名字(例如,大多数人没有博士学位)用作默认的后缀-以及null
在配置文件中未指定的配置选项。在第二种情况下,string.Empty
如果存在config选项,但将使用所需的配置值为空字符串,则将使用该选项。
null
来表示“没有后缀”?
它们与其他人已经回答的不同。
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比空值占用更多的内存,尽管我不会称它为污染..它只是另外一个字节。
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
。不知道为什么会这样,但是您去了。我现在只""
在各处使用以保持一致性。
.Length==0
或使用的习惯的原因.Compare()