在.NET中,String.Empty
和之间的区别是什么""
,它们是可互换的,还是存在一些基本的参考或本地化问题,这些问题String.Empty
将确保不是问题?
在版本2.0之前的.NET中,""
创建一个对象而不string.Empty
创建对象引用,这样可以string.Empty
提高效率.
在.NET 2.0及更高版本中,所有出现的""
引用都是相同的字符串文字,这意味着""
相当于.Empty
,但仍然没有那么快.Length == 0
.
.Length == 0
是最快的选择,但.Empty
代码稍微清晰.
有关更多信息,请参阅.NET规范.
String.Empty和""之间有什么区别,它们是可互换的
string.Empty
是只读字段,""
而是编译时常量.他们表现不同的地方是:
C#4.0或更高版本中的默认参数值
void SomeMethod(int ID, string value = string.Empty) // Error: Default parameter value for 'value' must be a compile-time constant { //... implementation }
switch语句中的case表达式
string str = ""; switch(str) { case string.Empty: // Error: A constant value is expected. break; case "": break; }
属性参数
[Example(String.Empty)] // Error: An attribute argument must be a constant expression, typeof expression // or array creation expression of an attribute parameter type
以前的答案对于.NET 1.1是正确的(查看他们链接的帖子的日期:2003).从.NET 2.0及更高版本开始,基本上没有区别.无论如何,JIT最终会引用堆上的相同对象.
根据C#规范,第2.4.4.5节:http://msdn.microsoft.com/en-us/library/aa691090( VS.71) .aspx
每个字符串文字不一定会产生新的字符串实例.当两个或多个根据字符串相等运算符(第7.9.7节)等效的字符串文字出现在同一个程序集中时,这些字符串文字引用相同的字符串实例.
有人甚至在Brad Abram的帖子中提到了这一点
总之,""与String.Empty的实际结果是零.JIT最终会弄明白.
我个人认为,JIT比我更聪明,所以我尽量不要对这样的微编译器优化过于聪明.JIT将展开()循环,删除冗余代码,内联方法等,比我或C#编译器可以预先预测的更合适的时间.让JIT完成它的工作:)
String.Empty
是一个只读字段,""
而是一个常量字段.这意味着您不能String.Empty
在switch语句中使用它,因为它不是常量.
另一个区别是String.Empty生成更大的CIL代码.虽然引用""和String.Empty的代码长度相同,但编译器不会针对String.Empty参数优化字符串连接(请参阅Eric Lippert的博客文章).以下等效功能
string foo() { return "foo" + ""; } string bar() { return "bar" + string.Empty; }
生成这个IL
.method private hidebysig instance string foo() cil managed { .maxstack 8 L_0000: ldstr "foo" L_0005: ret } .method private hidebysig instance string bar() cil managed { .maxstack 8 L_0000: ldstr "bar" L_0005: ldsfld string [mscorlib]System.String::Empty L_000a: call string [mscorlib]System.String::Concat(string, string) L_000f: ret }
上面的答案在技术上是正确的,但你真正想要使用的是,为了获得最佳的代码可读性和最小的异常机会,String.IsNullOrEmpty(s)
我倾向于使用String.Empty
而不是""
一个简单但不明显的原因:
"????????????????????"
并且""
不一样,第一个实际上有16个零宽度字符.显然,没有一个有能力的开发人员会在他们的代码中放入零宽度字符,但如果他们确实进入那里,那么这可能是一个维护噩梦.
笔记:
我在这个例子中使用了U + FEFF.
不确定是否会吃掉那些角色,但是你可以尝试使用多个零宽度字符中的一个
我只是感谢https://codegolf.stackexchange.com/
String.Empty不会创建对象,而""会创建对象.然而,正如这里指出的那样,差异是微不足道的.
没关系!
过去对此有一些讨论:
http://www.codinghorror.com/blog/archives/000185.html
http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx
http://blogs.msdn.com/brada/archive/2003/04/27/50014.aspx
""的所有实例都是相同的,实际的字符串文字(或它们应该是).因此,每次使用""时,你真的不会在堆上抛出一个新对象,而只是创建对同一个实体对象的引用.话虽如此,我更喜欢string.Empty.我认为它使代码更具可读性.
使用String.Empty
而不是""
.
这比速度比内存使用更多,但它是一个有用的提示.这
""
是一个文字,因此将作为文字:在第一次使用时它被创建,并且对于以下用途,它的引用被返回.""
无论我们使用它多少次,只有一个实例存储在内存中!我没有看到任何记忆惩罚.问题是每次""
使用时,都会执行一个比较循环来检查它""
是否已经在实习池中.另一方面,String.Empty
是对""
存储在.NET Framework内存区域中的引用.String.Empty
指向VB.NET和C#应用程序的相同内存地址.那么为什么每次需要""
时都会搜索引用String.Empty
?
参考:String.Empty
vs""