在。net中,String和。net之间的区别是什么?空和"",他们是可交换的,或者有一些潜在的引用或本地化问题,围绕相等的字符串。空将保证都不是问题?
当前回答
Eric Lippert写道(2013年6月17日):“我在c#编译器中工作过的第一个算法是处理字符串连接的优化器。不幸的是,在我离开Roslyn之前,我没有设法将这些优化移植到Roslyn代码库中;希望有人能做到!”
以下是截至2019年1月的一些Roslyn x64结果。尽管本页上的其他答案是一致的,但在我看来,当前的x64 JIT并没有将所有这些情况都一视同仁。
但是要特别注意,这些示例中只有一个最终调用了String。Concat,我猜这是由于模糊的正确性原因(而不是优化疏忽)。其他的差异似乎很难解释。
default(String) + { default(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 }
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 str=null;
Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference.
string str = string.Empty;
Console.WriteLine(str.Length); // 0
所以它似乎“Null”意味着绝对无效和“字符串。“空”表示它包含某种值,但它是空的。
上面的答案在技术上是正确的,但你可能真正想要使用的是String.IsNullOrEmpty(s),以获得最好的代码可读性和最小的异常机会。
字符串。Empty是只读字段,而""是const字段。这意味着您不能使用String。在switch语句中为空,因为它不是常量。
这都不重要!
以前的一些讨论:
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
""的所有实例都是相同的,被分隔的字符串字面量(或者它们应该是)。因此,每次使用""时,实际上不会在堆上抛出一个新对象,而只是创建一个对相同的内部对象的引用。话虽如此,我还是更喜欢字符串。我认为这使代码更具可读性。
推荐文章
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- Printf与std::字符串?
- AppSettings从.config文件中获取值
- 如何检查IEnumerable是否为空或空?
- 不区分大小写的“in”
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 如何在PHP中截断字符串最接近于一定数量的字符?
- 如何在iis7应用程序池中设置。net Framework 4.5版本
- 如何分裂()一个分隔字符串到一个列表<字符串>
- Ruby数组到字符串的转换
- 如何指定最小值,但没有使用范围数据注释属性的最大小数?
- 如何在PowerShell中获得本地主机名?