在。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.IsNullOrEmpty(s),以获得最好的代码可读性和最小的异常机会。
因为字符串。Empty不是编译时常量,不能在函数定义中使用它作为默认值。
public void test(int i=0,string s="")
{
// Function Body
}
我倾向于使用String。空而不是"",原因很简单,但并不明显: “”和“”是不一样的,第一个实际上有16个零宽度字符。显然,没有一个有能力的开发人员会在他们的代码中放入零宽度字符,但如果他们真的这样做了,那将是一个维护的噩梦。
注:
在这个例子中,我使用了U+FEFF。 不确定SO是否会吃掉这些字符,但请自己尝试使用许多零宽度字符中的一个 多亏了https://codegolf.stackexchange.com/,我才发现了这一点
字符串之间的区别是什么。空和“”,是他们 可以互换
字符串。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语句中的大小写表达式
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
从实体框架的角度来看:EF版本6.1.3似乎处理字符串。在验证时,Empty和""不同。
字符串。出于验证目的,Empty被视为空值,如果在Required(带属性)字段上使用,则会抛出验证错误;其中as ""将通过验证而不抛出错误。
这个问题可以在EF 7+中解决。参考: - https://github.com/aspnet/EntityFramework/issues/2610)。
编辑:[Required(AllowEmptyStrings = true)]将解决此问题,允许字符串。为空进行验证。
推荐文章
- Python csv字符串到数组
- 在c#中从URI字符串获取文件名
- 检查SqlDataReader对象中的列名
- 如何将类标记为已弃用?
- c# 8支持。net框架吗?
- 是否有可能更新一个本地化的故事板的字符串?
- 为什么字符串类型的默认值是null而不是空字符串?
- 在Python中包装长行
- AutoMapper:“忽略剩下的?”
- 如何找出一个文件存在于c# / .NET?
- string. isnullorempty (string) vs. string. isnullowhitespace (string)
- 完全外部连接
- 如何检查字符串的特定字符?
- Haskell:将Int转换为字符串
- 如何使用。net 4运行时运行PowerShell ?