String.Empty
和""
有什么区别?它们是否可以互换使用,或者在相等性方面是否存在基础引用或本地化问题,String.Empty
可以确保这些问题不会成为问题?String.Empty
和""
有什么区别?它们是否可以互换使用,或者在相等性方面是否存在基础引用或本地化问题,String.Empty
可以确保这些问题不会成为问题?string mystring = "";
ldstr ""
ldstr
指令会将存储在元数据中的字符串字面量推送到新的对象引用中。
string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty
ldsfld
将静态字段的值推送到评估堆栈上。
我倾向于使用String.Empty
而不是""
,因为我认为它更清晰,不那么像VB语言。
var i = 30;
var f = Math.Pi;
var s = "";
var d = 22.2m;
var t = "I am some text";
var e = string.Empty;
\u00ad
。 - PalecEric Lippert 写道(2013年6月17日):
“我在C#编译器上处理字符串连接的优化算法是我曾经处理过的第一个算法。不幸的是,在我离开之前,我没有将这些优化移植到Roslyn代码库中; 希望有人能够做到这一点!”
以下是截至2019年1月的一些Roslyn x64结果。尽管本页其他答案的共识意见是相同的,但在我的看来,当前的x64 JIT并未将所有这些情况视为相同,毕竟如此。
请特别注意,这些示例中只有一个实际上会调用String.Concat
,我猜测这是出于晦涩的正确性原因(而不是优化失误)。其他差异似乎更难解释。
default(String) + { default(String), "", String.Empty }
默认值(String)+ { 默认值(String),“”,String.Empty }static String s00() => default(String) + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s01() => default(String) + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s02() => default(String) + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
"" + { default(String), "", String.Empty }
翻译为:将空字符串与{默认字符串,空字符串,空字符串}连接。static String s03() => "" + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s04() => "" + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s05() => "" + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
String.Empty + { default(String), "", String.Empty }
空字符串 + { 默认(String), "", 空字符串 }static String s06() => String.Empty + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s07() => String.Empty + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s08() => String.Empty + String.Empty;
mov rcx,[String::Empty]
mov rcx,qword ptr [rcx]
mov qword ptr [rsp+20h],rcx
mov rcx,qword ptr [rsp+20h]
mov rdx,qword ptr [rsp+20h]
call F330CF60 ; <-- String.Concat
nop
add rsp,28h
ret
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
AMD64 Release
[MethodImpl(MethodImplOptions.NoInlining)]
'SuppressJitOptimization' = false
由于String.Empty不是编译时常量,因此您不能在函数定义中将其用作默认值。
public void test(int i=0,string s="")
{
// Function Body
}
public void test(int i=0, string s=string.Empty) {}
中的摘要会编译失败,并提示 "Default parameter value for 's' must be a compile-time constant"。OP 的答案是可行的。 - bugybunnystring.Empty
。有些开发人员可能无法区分""
和" "
,而string.Empty
则很清晰。""
,但在这种情况下,我想知道为什么方法不使用string?= null
来代替默认参数(对于视力受损者也更易读)。非常感谢您提供的信息丰富的答案。
如果我错了,请原谅我的无知。我正在使用VB,但我认为如果您测试未分配字符串的长度(即IS Nothing),它会返回错误。现在,我从1969年开始编程,所以我已经被远远落下了,但是我一直通过连接空字符串(“”)来测试字符串。例如(用任何语言):-
if string + "" = ""
这里的每个人都提供了一些很好的理论解释。我有一个类似的疑问。所以我尝试了一些基本的编码,并发现了一个区别。以下是这个区别。
string str=null;
Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference.
string str = string.Empty;
Console.WriteLine(str.Length); // 0
看起来,“Null” 表示绝对的空无,而“String.Empty”表示它包含某种值,但是为空。
""
和string.Empty
的区别。仅在尝试确定字符串是否为空时,才提到了null
。 - Palec
string.Empty
,并且为什么将其声明为readonly
而不是const
,背后的原因是什么。 - user1451111