最近,我的一位同事告诉我不要使用 string.Empty
来设置字符串变量,而是使用 null
,因为它会污染堆栈。
他说不要这样做:
string myString=string.Empty;
而是这样做:string mystring=null;
这真的有关系吗?我知道 string 是一个对象,所以这种做法有点合理。
我知道这是个愚蠢的问题,但你怎么看?
null
和 Empty
是非常不同的,我不建议随意在它们之间切换。但是两者都没有额外的“成本”,因为Empty
是一个单一的固定引用(你可以使用任意次数)。
使用ldsfld 不会在堆栈上造成任何“污染” - 这个担忧是有点疯狂的。加载 null
可能略微更便宜,但如果你不小心检查值,可能会导致空引用异常。
就我个人而言,我两者都不使用... 如果我想要一个空字符串,我使用 ""
- 简单明了。由于字符串被纳入,这也没有每次使用的额外开销。
在IL级别上,这里 "" 和 Empty 的区别仅仅是 ldstr vs ldsfld - 但两者都给出相同的单个 interned 字符串引用。此外,在较新的.NET版本中,JIT直接拦截这些操作,产生空字符串引用,而无需实际进行静态字段查找。基本上,除了可读性外,无需关心任何原因。我只使用 ""。
""
代替冗长的样板代码,这是一个好习惯。谁会支持这种无聊的做法?@Jalal,Brad Abrams的帖子已经过时了,如果编译器仍然不能将这两个代码优化为相同的结果,那么微软就应该感到羞耻!但我们不需要去修复他们的工作。实际上,我们也不需要:在第二个链接中,Lasse(在评论中)比较了使用任一变量进行比较的汇编输出:它们是相同的。 - Konrad Rudolphnew String(new char[]{})
,所以你的比较并不适用。此外:“这也与代码有多少字符无关” - 不,从某种程度上来说,它是有关系的。不必要的代码会导致视觉混乱,降低可读性。 - Konrad Rudolph它并不会“污染堆栈”,虽然没有技术上的原因,但是将一个变量设置为对象的引用(即使是空字符串)和使用 null
是有很大区别的。它们不是同一件事,应该以不同的方式使用。
null
应该用于指示缺少数据,string.Empty
(或者 ""
)则表示存在数据,实际上是空文本。您是否有某种情况不确定何时使用哪种方法最合适?
编辑,添加示例:
您可以将 string.Empty
用作人名的默认后缀(例如,大多数人没有博士学位)
您可以在配置文件中未指定配置选项时使用 null
。 在这种情况下,如果配置选项存在但所需的配置值为空字符串,则使用 string.Empty
。
string.Empty
或 ""
,而当你想要指示没有数据时,请使用 null
。你可以将 string.Empty
用作人名的默认后缀(大多数人没有博士学位),并将 null
用于未在配置文件中指定的配置选项。在第二种情况下,如果配置选项存在但所需的配置值为空字符串,则使用 string.Empty
。 - Kieren Johnstonestatic 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);
}
结果:
在处理空字符串和null字符串时,当您需要将其保存到平面文件或通过通信传输时,这变成了一个问题。因此,我认为为其他访问此页面的人提供特定问题的好解决方案可能会很有用。
为了将字符串保存到文件或通过通信进行通信:
您可能希望将字符串转换为字节。
我建议的一个好习惯是在转换后的字符串中添加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},可以保存并稍后加载并解释回为空字符串。 另一方面,如果我在字符串中有null值,则最终只会得到{0}作为要保存的字节数组,再次加载时可以解释回null。
还有更多好处,例如知道要加载或累积的大小(如果您拥有多个字符串)。
回到主题-它将……某种程度上会污染栈,因为任何系统都使用相同的原则区分null和empty..。因此是的,string.Empty占用的内存比null多,尽管我不会称其为污染..它只是多了1个字节。
这个问题已经被反复回答了,但是 null 表示没有值,而不是未初始化。string.Empty 表示 ""(一个空字符串),正如在 MSDN 上所述。
检查空字符串或 null 的最安全的方法是使用 string.IsNullOrEmpty。
顺便说一下,我发现混合使用""
和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()
的习惯。 - zanlok
string.Empty
、""
和null
都是常量值,但它们都足够“简单”,我不明白为什么你要将其中一个分配给一个变量。如果你需要捕获一个out
变量,为什么不直接使用string myString;
? - stusmithString.Empty
;如果你不知道某人是否有中间名,则使用null
)。然后,编写清晰正确、易于维护的代码。 - jasonnull
表示"没有中间名"呢?我将空字符串解释为"有中间名,但为空",这听起来很奇怪。 - OfirD