在C#中,我应该使用string.空或string.空或“”来初始化字符串吗?

在C#中,我想用一个空字符串初始化一个字符串值。

我该怎么做?什么是正确的方法,为什么?

string willi = string.Empty;

string willi = String.Empty;

string willi = "";

不然呢?

308551 次浏览

我个人更喜欢“除非有充分的理由去做更复杂的事情。

以上任何一种。

有很多很多更好的事情可以夸夸其谈。比如什么颜色的树皮最适合一棵树,我认为模糊的棕色带有淡淡的苔藓。

我使用第三个,但其他两个第一个似乎不那么奇怪。string是String的别名,但是在赋值中看到它们感觉不对劲。

从长远来看,编译器应该使它们都是一样的。选择一个标准,这样你的代码就很容易阅读,并坚持下去。

我认为第二个是“正确的”,但老实说,我认为这无关紧要。编译器应该足够聪明,可以将其中任何一个编译为完全相同的字节码。我自己使用“”。

我更喜欢string而不是String。选择string.Empty而不是""是一个选择并坚持下去的问题。使用string.Empty的优点是它非常明显你的意思,你不会意外地复制不可打印的字符,比如""中的"\x003"

我没什么区别。不过,最后一个是最快打字的:)

String.Emptystring.Empty是等价的。String是BCL类名;string是它的C#别名(或快捷方式,如果你愿意的话)。与Int32int相同。有关更多示例,请参阅的文档

至于"",我真的不确定。

就个人而言,我总是使用string.Empty

前两个中的任何一个对我来说都是可以接受的。我会避免最后一个,因为通过在引号之间放置空格来引入bug相对容易。这个特定的bug很难通过观察找到。假设没有拼写错误,所有这些在语义上都是等价的。

[编辑]

此外,您可能希望始终使用stringString来保持一致性,但这只是我。

stringSystem.String类型的同义词,它们是相同的。

值也相同:string.Empty == String.Empty == ""

我不会在代码中使用字符常量“”,而是string.EmptyString.Empty-更容易理解程序员的意思。

stringString之间,我更喜欢小写string,因为我曾经使用Delphi很多年,而Delphi风格是小写string

所以,如果我是你的老板,你会写string.Empty

这并不重要-它们完全相同。但是,最重要的是你必须一致

附注:我一直在为这种“正确的事情”而斗争。

最好的代码是根本没有代码

编码的基本本质是,作为程序员,我们的任务是认识到我们所做的每一个决定都是权衡. […] #

因此,更少的代码是更好的代码:首选""而不是string.EmptyString.Empty。这两个是长六倍,没有额外的好处-当然没有增加清晰度,因为它们表达了完全相同的信息。

我不想插话,但我看到一些错误的信息被扔到这里。

就我个人而言,我更喜欢0。这是个人偏好,我会根据具体情况服从与我合作的任何团队的意愿。

正如一些人提到的,string.EmptyString.Empty之间没有任何区别。

此外,这是一个鲜为人知的事实,使用“”是完全可以接受的。在其他环境中,“”的每个实例都会创建一个对象。然而,. NET实习它的字符串,所以未来的实例将从实习生池中提取相同的不可变字符串,任何性能损失都可以忽略不计。

使用您和您的团队认为最具可读性的任何内容。

其他答案建议每次使用""时都会创建一个新字符串。这不是真的——由于字符串实习,它将在每个程序集或每个AppDomain创建一次(或者可能在整个过程中创建一次——在这方面不确定)。这种差异可以忽略不计——很大程度上,大规模微不足道。

但是,你觉得哪个更具可读性是另一回事。它是主观的,因人而异——所以我建议你找出你的团队中大多数人喜欢什么,为了一致性,所有人都这样做。就我个人而言,我觉得0更容易阅读。

""" "很容易被误认为对方的论点并没有真正被我所接受。除非您使用比例字体(并且我没有与任何开发人员合作过),否则很容易分辨出区别。

虽然差异非常非常小,但差异仍然存在。

  1. ""创建了一个对象,而String.Empty没有。但是这个对象将被创建一次,如果代码中还有另一个"",稍后将从字符串池中引用。

  2. Stringstring是相同的,但我建议使用String.Empty(以及String.FormatString.Copy等),因为点符号表示类,而不是运算符,并且类以大写字母开头符合C#编码标准。

除了其他原因,我更喜欢字符串.空,以确保您知道它是什么,并且您没有意外删除内容,主要是为了国际化。如果我看到引号中的字符串,那么我总是不得不怀疑这是否是新代码,并且应该将其放入字符串表中。因此,每次代码更改/审查时,您都需要查找“引号中的内容”,是的,您可以过滤掉空字符串,但我告诉人们,除非您知道它不会本地化,否则永远不要将字符串放入引号中是一个好习惯。

几乎每个开发人员都会知道“”的意思。我第一次亲自遇到String.空,不得不花一些时间搜索谷歌以确定他们是否真的完全相同的东西。

从性能和代码生成的角度来看,真的没有什么区别。在性能测试中,他们在哪个更快与另一个更快之间来回切换,并且只有毫秒。

在查看幕后代码时,你也看不到任何区别。唯一的区别是IL,它string.Empty使用操作码ldsfld""使用操作码ldstr,但这只是因为string.Empty是静态的,并且两个指令都做同样的事情。如果您查看生成的组件,则完全相同。

C#代码

private void Test1(){string test1 = string.Empty;string test11 = test1;}
private void Test2(){string test2 = "";string test22 = test2;}

IL代码

.method private hidebysig instance voidTest1() cil managed{// Code size       10 (0xa).maxstack  1.locals init ([0] string test1,[1] string test11)IL_0000:  nopIL_0001:  ldsfld     string [mscorlib]System.String::EmptyIL_0006:  stloc.0IL_0007:  ldloc.0IL_0008:  stloc.1IL_0009:  ret} // end of method Form1::Test1
.method private hidebysig instance voidTest2() cil managed{// Code size       10 (0xa).maxstack  1.locals init ([0] string test2,[1] string test22)IL_0000:  nopIL_0001:  ldstr      ""IL_0006:  stloc.0IL_0007:  ldloc.0IL_0008:  stloc.1IL_0009:  ret} // end of method Form1::Test2

汇编码

        string test1 = string.Empty;0000003a  mov         eax,dword ptr ds:[022A102Ch]0000003f  mov         dword ptr [ebp-40h],eax
string test11 = test1;00000042  mov         eax,dword ptr [ebp-40h]00000045  mov         dword ptr [ebp-44h],eax
        string test2 = "";0000003a  mov         eax,dword ptr ds:[022A202Ch]00000040  mov         dword ptr [ebp-40h],eax
string test22 = test2;00000043  mov         eax,dword ptr [ebp-40h]00000046  mov         dword ptr [ebp-44h],eax

这完全是一个代码风格的偏好,做如何。NET处理字符串。但是,这里有我的意见:)

在访问静态方法、属性和字段时,我总是使用BCL类型名称:String.EmptyInt32.TryParse(...)Double.Epsilon

在声明新实例时,我总是使用C#关键字:int i = 0;string foo = "bar";

我很少使用未声明的字符串文字,因为我喜欢能够扫描代码将它们组合成可重用的命名常量。编译器无论如何都会用文字替换常量,所以这更多的是一种避免魔法字符串/数字的方法,并通过名称赋予它们更多的意义。另外,更改值更容易。

一个区别是,如果你使用switch-case语法,你不能写case string.Empty:,因为它不是常量。你得到一个Compilation error : A constant value is expected

查看更多信息:字符串-空-对-空-引号

关于http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx

正如David所暗示的,String.Empty""之间的差异很小,但是有区别。""实际上创建了一个对象,它可能会从字符串实习生池中拉出,但仍然…而String.Empty没有创建任何对象…所以如果你真的在寻找最终的内存效率,我建议String.Empty。然而,你应该记住差异是如此微不足道,你永远不会在你的代码中看到它…
至于System.String.Emptystring.EmptyString.Empty…我的护理水平很低;-)

没有人提到在VisualStudio String中颜色编码与字符串不同。这对于易读性很重要。此外,小写通常用于vars和type,没什么大不了的,但String.空是一个常量,而不是var或type。

我更喜欢string.Empty而不是String.Empty,因为您可以使用它而无需在文件中包含using System;

至于选择""还是string.Empty,这是个人偏好,应该由你的团队决定。

这个话题又长又旧,所以如果这种行为在其他地方被提到过,请原谅我。(并指出涵盖此内容的答案)

如果您使用string.Empty或双引号,我发现编译器的行为存在差异。如果您不使用使用string.空或双引号初始化的字符串变量,差异就会显示出来。

如果使用string.Empty初始化,则编译器警告

CS0219 - The variable 'x' is assigned but its value is never used

永远不会发出,而在使用双引号初始化的情况下,您会得到预期的消息。

此链接的Connect文章中解释了此行为:https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value

基本上,如果我做对了,他们希望允许程序员设置一个带有函数返回值的变量用于调试目的,而不用警告消息打扰他,因此他们仅在昂贵的赋值和字符串的情况下限制警告。

我在. NET v4.5控制台应用程序中使用以下方法执行了一个简单的测试:

private static void CompareStringConstants(){string str1 = "";string str2 = string.Empty;string str3 = String.Empty;Console.WriteLine(object.ReferenceEquals(str1, str2)); //prints TrueConsole.WriteLine(object.ReferenceEquals(str2, str3)); //prints True}

这表明所有三个变量,即str1str2str3,尽管使用不同的语法初始化,但都指向内存中相同的字符串(零长度)对象。

所以在内部它们没有区别。这一切都归结为您或您的团队想要使用哪一个的便利性。字符串类的这种行为在. NET Framework中被称为字符串实习。Eric Lippert有一个非常好的博客这里描述了这个概念。

我只是在看一些代码,这个问题突然出现在我的脑海中,我以前读过一段时间。这当然是一个易读性的问题。

考虑以下C#代码…

(customer == null) ? "" : customer.Name

vs

(customer == null) ? string.empty : customer.Name

我个人认为后者不那么模棱两可,更容易阅读。

正如其他人所指出的,实际差异可以忽略不计。

我亲眼目睹了""两次导致(小)问题。一次是由于一个刚接触基于团队的编程的初级开发人员的错误,另一次是一个简单的错字,但事实是使用string.Empty本可以避免这两个问题。

是的,这在很大程度上是一个判断,但是当一种语言为您提供多种做事方式时,我倾向于倾向于具有最多编译器监督和最强编译时强制执行的语言。那就是没有""。这一切都是为了表达特定的意图。

如果你键入string.EMptyStrng.Empty,编译器会让你知道你做到了错误。立即。它根本不会编译。作为开发人员,你引用特定的意图是编译器(或其他开发人员)不能以任何方式误解,当你做错了,你不能创建bug。

如果您在表示""时键入" ",反之亦然,编译器会很乐意按照您的要求进行。另一个开发人员可能无法收集您的特定意图。创建的错误

早在string.Empty出现之前,我就使用了定义EMPTY_STRING常量的标准库。我们仍然在案件语句中使用该常量在哪里string.Empty不允许

只要有可能,让编译器为你工作,并消除人为错误的可能性,无论多小。在我看来,这胜过其他人引用的“易读性”。

特异性和编译时执行。这就是晚餐的内容。

我使用“”是因为它在我的代码中会被明显地涂成黄色……出于某种原因,String。空在我的Visual Studio Code主题中全是白色。我相信这对我来说最重要。

空字符串就像空集,每个人都用它来命名""。同样在形式语言中,由字母表创建的长度为零的字符串称为空字符串。set和string都有一个特殊的符号。空字符串:ε和空集:。如果你想谈论这个零长度的字符串,你会称之为空字符串,这样每个人都确切地知道你指的是什么。现在如果你把它命名为空字符串,为什么不在代码中使用string.Empty,这表明意图是明确的。缺点是它不是一个常量,因此不能在任何地方使用,就像在属性中一样。(由于某些技术原因,它不是常数,请参阅参考来源。

这可能是一个有争议的评论,但是,总的来说,我发现当我与微软保持一致时,我的生活会更轻松。我们不可能知道他们做事的全部深层原因(有时非常严格,有时我想是笨拙的)。

他们在像Assembly文件这样的自动生成的文件中使用“”,所以这就是我所做的。事实上,当我尝试将下面的任何“”替换为String.空时,Visual Studio会崩溃。这可能有一个合乎逻辑的解释,但以我有限的知识,如果我只是做他们做的事情,大多数时候,事情都会解决。(魂斗罗:我知道他们一些自动生成的文件也使用String.空,这打破了我的观点。:))

<Assembly: System.Reflection.AssemblyCulture("")><Assembly: System.Reflection.AssemblyDescription("")><Assembly: System.Reflection.AssemblyFileVersion("1.0.0.0")><Assembly: System.Reflection.AssemblyKeyFile("")><Assembly: System.Reflection.AssemblyProduct("")><Assembly: System.Reflection.AssemblyTitle("")>

如果你想恶作剧某人,把"‍"放入他们的代码中。这不是空字符串,它是"\u200D"。你不能用string.Empty愚弄某人。