String.Empty 和 "" 之间有什么区别 (空字符串)?
在 .NET 中,String.Empty
和 ""
之间有什么区别,它们是否可以互换,或者是否存在一些关于等式的潜在引用或本地化问题 String.Empty
会确保没有问题吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在 .NET 中,String.Empty
和 ""
之间有什么区别,它们是否可以互换,或者是否存在一些关于等式的潜在引用或本地化问题 String.Empty
会确保没有问题吗?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(18)
在 2.0 版本之前的 .NET 中,
""
创建一个对象,而string.Empty
不创建对象ref,这使得string.Empty
更加高效。在 .NET 2.0 及更高版本中,所有出现的
""
都引用相同的字符串文字,这意味着""
等效于.Empty
,但仍然不如.Length == 0
快。.Length == 0
是最快的选项,但.Empty
可以使代码稍微干净一些。有关详细信息,请参阅.NET 规范。
In .NET prior to version 2.0,
""
creates an object whilestring.Empty
creates no objectref, which makesstring.Empty
more efficient.In version 2.0 and later of .NET, all occurrences of
""
refer to the same string literal, which means""
is equivalent to.Empty
, but still not as fast as.Length == 0
..Length == 0
is the fastest option, but.Empty
makes for slightly cleaner code.See the .NET specification for more information.
string.Empty
是只读字段,而""
是编译时常量。 它们表现不同的地方是:C# 4.0 或更高版本中的默认参数值
switch 语句中的 Case 表达式
属性参数
string.Empty
is a read-only field whereas""
is a compile time constant. Places where they behave differently are:Default Parameter value in C# 4.0 or higher
Case expression in switch statement
Attribute arguments
之前的答案对于 .NET 1.1 是正确的(查看他们链接的帖子的日期:2003 年)。 从 .NET 2.0 及更高版本开始,本质上没有区别。 无论如何,JIT 最终都会引用堆上的同一个对象。
根据 C# 规范,第 2.4.4.5 节:
http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
甚至有人在 Brad Abram 的帖子评论中提到了这一点
综上所述,“” vs. String.Empty 的实际结果是 nil。 JIT 最终会解决这个问题。
我个人发现 JIT 比我聪明得多,所以我尽量不要对这样的微编译器优化过于聪明。 JIT 将在更合适的时间更好地展开 for() 循环、删除冗余代码、内联方法等,这比我或 C# 编译器事先预期的要好。 让 JIT 完成它的工作:)
The previous answers were correct for .NET 1.1 (look at the date of the post they linked: 2003). As of .NET 2.0 and later, there is essentially no difference. The JIT will end up referencing the same object on the heap anyhow.
According to the C# specification, section 2.4.4.5:
http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
Someone even mentions this in the comments of Brad Abram's post
In summary, the practical result of "" vs. String.Empty is nil. The JIT will figure it out in the end.
I have found, personally, that the JIT is way smarter than me and so I try not to get too clever with micro-compiler optimizations like that. The JIT will unfold for() loops, remove redundant code, inline methods, etc better and at more appropriate times than either I or the C# compiler could ever anticipate before hand. Let the JIT do its job :)
String.Empty
是一个只读字段,而""
是一个const。 这意味着您不能在 switch 语句中使用 String.Empty,因为它不是常量。String.Empty
is a readonly field while""
is a const. This means you can't useString.Empty
in a switch statement because it is not a constant.我倾向于使用
String.Empty
而不是""
,原因很简单,但并不明显:""
和""
不一样,第一个实际上有 16其中的零宽度字符。 显然,没有称职的开发人员会将零宽度字符放入他们的代码中,但如果他们确实这样做,这可能会成为维护的噩梦。注意:
在此示例中我使用了 U+FEFF .
不确定SO是否会吃掉这些字符,但请自己尝试使用众多零宽度字符之一
多亏https://codegolf.stackexchange.com/
我才发现这个
I tend to use
String.Empty
rather than""
for one simple, yet not obvious reason:""
and""
are NOT the same, the first one actually has 16 zero width characters in it. Obviously no competent developer is going to put and zero width characters into their code, but if they do get in there, it can be a maintenance nightmare.Notes:
I used U+FEFF in this example.
Not sure if SO is going to eat those characters, but try it yourself with one of the many zero-width characters
I only came upon this thanks to https://codegolf.stackexchange.com/
另一个区别是 String.Empty 生成更大的 CIL 代码。 虽然引用“”和 String.Empty 的代码长度相同,但编译器不会优化字符串连接(请参阅 Eric Lippert 的 博客文章) 用于 String.Empty 参数。 以下等效函数
生成此 IL
Another difference is that String.Empty generates larger CIL code. While the code for referencing "" and String.Empty is the same length, the compiler doesn't optimize string concatenation (see Eric Lippert's blog post) for String.Empty arguments. The following equivalent functions
generate this IL
上述答案在技术上是正确的,但为了获得最佳的代码可读性和最小的异常机会,您可能真正想要使用的是 String.IsNullOrEmpty(s)
The above answers are technically correct, but what you may really want to use, for best code readability and least chance of an exception is String.IsNullOrEmpty(s)
“”的所有实例都是相同的、内部字符串文字(或者它们应该是)。 因此,每次使用“”时,您实际上不会在堆上抛出一个新对象,而只是创建对同一内部对象的引用。 话虽如此,我更喜欢 string.Empty。 我认为这使代码更具可读性。
All instances of "" are the same, interned string literal (or they should be). So you really won't be throwing a new object on the heap every time you use "" but just creating a reference to the same, interned object. Having said that, I prefer string.Empty. I think it makes code more readable.
String.Empty 不会创建对象,而 "" 会创建对象。 正如此处所指出的,差异是微不足道的,然而。
String.Empty does not create an object whereas "" does. The difference, as pointed out here, is trivial, however.
使用
String.Empty
而不是""
。参考:
String.Empty
与 <代码>“”Use
String.Empty
rather than""
.Reference:
String.Empty
vs""
ldstr 将新对象引用推送到存储在元数据中的字符串文字。
ldsfld
将静态字段的值推送到计算堆栈上我倾向于使用
String.Empty
而不是""
因为恕我直言,它更清晰、更少VB 左右。ldstr
pushes a new object reference to a string literal stored in the metadata.ldsfld
pushes the value of a static field onto the evaluation stackI tend to use
String.Empty
instead of""
because IMHO it's clearer and less VB-ish.当您以视觉方式扫描代码时,“”会以与字符串着色的方式显示颜色。 string.Empty 看起来像常规的类成员访问。 快速查看时,更容易发现“”或凭直觉了解其含义。
找出字符串(堆栈溢出着色并不完全有帮助,但在 VS 中这更明显):
When you're visually scanning through code, "" appears colorized the way strings are colorized. string.Empty looks like a regular class-member-access. During a quick look, its easier to spot "" or intuit the meaning.
Spot the strings (stack overflow colorization isn't exactly helping, but in VS this is more obvious):
以下是截至 2019 年 1 月的一些 Roslyn x64 结果。尽管其他答案达成了共识在此页面上,在我看来,当前的 x64 JIT 并没有以相同的方式处理所有这些情况。
但请特别注意,这些示例中只有一个实际上最终调用了 String.Concat,我猜测这是出于模糊的正确性原因(而不是优化监督)。 其他差异似乎更难以解释。
默认(字符串) + { 默认(字符串), "", String.Empty }
"" + { 默认(字符串), "", String.Empty }
String.Empty + { 默认(字符串), "", 字符串.空}
Test details
Here are some Roslyn x64 results as of January 2019. Despite the consensus remarks of the other answers on this page, it does not appear to me that the current x64 JIT is treating all of these cases identically, when all is said and done.
Note in particular, however, that only one of these examples actually ends up calling
String.Concat
, and I'm guessing that that's for obscure correctness reasons (as opposed to an optimization oversight). The other differences seem harder to explain.default(String) + { default(String), "", String.Empty }
"" + { default(String), "", String.Empty }
String.Empty + { default(String), "", String.Empty }
Test details
从实体框架的角度来看:EF 版本 6.1.3 在验证时似乎以不同方式对待 String.Empty 和 ""。
string.Empty 出于验证目的被视为空值,如果在必需(属性)字段上使用它,则会引发验证错误; 其中“”将通过验证并且不会引发错误。
此问题可能在 EF 7+ 中得到解决。 参考:
- https://github.com/aspnet/EntityFramework/issues/2610 )。
编辑:[Required(AllowEmptyStrings = true)] 将解决此问题,允许 string.Empty 进行验证。
Coming at this from an Entity Framework point of view: EF versions 6.1.3 appears to treat String.Empty and "" differently when validating.
string.Empty is treated as a null value for validation purposes and will throw a validation error if it's used on a Required (attributed) field; where as "" will pass validation and not throw the error.
This problem may be resolved in EF 7+. Reference:
- https://github.com/aspnet/EntityFramework/issues/2610 ).
Edit: [Required(AllowEmptyStrings = true)] will resolve this issue, allowing string.Empty to validate.
由于 String.Empty 不是编译时常量,因此您不能将其用作函数定义中的默认值。
Since String.Empty is not a compile-time constant you cannot use it as a default value in function definition.
在大多数情况下使用 string.Empty 来提高可读性。 某些开发人员的视力可能无法区分
""
和" "
,其中string.Empty
很清楚。对于参数默认值,仍然必须使用
""
,但在这种情况下,我想知道为什么该方法不使用string? = null
而不是默认参数。(对于视觉障碍者来说也更具可读性)Use
string.Empty
in most cases for readability. Some developer's vision might not be able to tell the difference of""
and" "
, wherestring.Empty
is clear.For parameter defaults will still have to use
""
, but in that case, I wonder why the method does not usestring? = null
instead for a defaulted param.(also more readable for the visually impared)感谢您提供非常有用的答案。
如果我错了,请原谅我的无知。 我正在使用 VB,但我认为如果您测试未分配字符串的长度(即 IS Nothing),它会返回错误。 现在,我从 1969 年开始编程,所以我已经远远落后了,但我总是通过连接空字符串 ("") 来测试字符串。 例如(无论何种语言): -
if string + "" = ""
Thanks for a very informative answer.
Forgive my ignorance if I'm wrong. I'm using VB but I think if you test the length of an unassigned string (i.e. IS Nothing), it returns an error. Now, I started programming in 1969, so I've been left well behind, however I have always tested strings by concatenating an empty string (""). E.g. (in whatever language): -
if string + "" = ""
这里的每个人都给出了一些很好的理论澄清。 我也有类似的疑问。 所以我尝试了一个基本的编码。 我发现了一个不同之处。 这就是区别。
所以看起来“Null”意味着绝对无效和无效。 “String.Empty”意味着它包含某种值,但它是空的。
Everybody here gave some good theoretical clarification. I had a similar doubt. So I tried a basic coding on it. And I found a difference. Here's the difference.
So it seems "Null" means absolutely void & "String.Empty" means It contains some kind of value, but it is empty.