在C#中,我想用一个空字符串初始化一个字符串值。
我该怎么做?什么是正确的方法,为什么?
string willi = string.Empty;
或
string willi = String.Empty;
string willi = "";
不然呢?
我个人更喜欢“除非有充分的理由去做更复杂的事情。
以上任何一种。
有很多很多更好的事情可以夸夸其谈。比如什么颜色的树皮最适合一棵树,我认为模糊的棕色带有淡淡的苔藓。
我使用第三个,但其他两个第一个似乎不那么奇怪。string是String的别名,但是在赋值中看到它们感觉不对劲。
从长远来看,编译器应该使它们都是一样的。选择一个标准,这样你的代码就很容易阅读,并坚持下去。
我认为第二个是“正确的”,但老实说,我认为这无关紧要。编译器应该足够聪明,可以将其中任何一个编译为完全相同的字节码。我自己使用“”。
我更喜欢string而不是String。选择string.Empty而不是""是一个选择并坚持下去的问题。使用string.Empty的优点是它非常明显你的意思,你不会意外地复制不可打印的字符,比如""中的"\x003"。
string
String
string.Empty
""
"\x003"
我没什么区别。不过,最后一个是最快打字的:)
String.Empty和string.Empty是等价的。String是BCL类名;string是它的C#别名(或快捷方式,如果你愿意的话)。与Int32和int相同。有关更多示例,请参阅的文档。
String.Empty
Int32
int
至于"",我真的不确定。
就个人而言,我总是使用string.Empty。
前两个中的任何一个对我来说都是可以接受的。我会避免最后一个,因为通过在引号之间放置空格来引入bug相对容易。这个特定的bug很难通过观察找到。假设没有拼写错误,所有这些在语义上都是等价的。
[编辑]
此外,您可能希望始终使用string或String来保持一致性,但这只是我。
string是System.String类型的同义词,它们是相同的。
System.String
值也相同:string.Empty == String.Empty == ""
string.Empty == String.Empty == ""
我不会在代码中使用字符常量“”,而是string.Empty或String.Empty-更容易理解程序员的意思。
在string和String之间,我更喜欢小写string,因为我曾经使用Delphi很多年,而Delphi风格是小写string。
所以,如果我是你的老板,你会写string.Empty
这并不重要-它们完全相同。但是,最重要的是你必须一致
附注:我一直在为这种“正确的事情”而斗争。
最好的代码是根本没有代码:
编码的基本本质是,作为程序员,我们的任务是认识到我们所做的每一个决定都是权衡. […] #
因此,更少的代码是更好的代码:首选""而不是string.Empty或String.Empty。这两个是长六倍,没有额外的好处-当然没有增加清晰度,因为它们表达了完全相同的信息。
我不想插话,但我看到一些错误的信息被扔到这里。
就我个人而言,我更喜欢0。这是个人偏好,我会根据具体情况服从与我合作的任何团队的意愿。
正如一些人提到的,string.Empty和String.Empty之间没有任何区别。
此外,这是一个鲜为人知的事实,使用“”是完全可以接受的。在其他环境中,“”的每个实例都会创建一个对象。然而,. NET实习它的字符串,所以未来的实例将从实习生池中提取相同的不可变字符串,任何性能损失都可以忽略不计。
使用您和您的团队认为最具可读性的任何内容。
其他答案建议每次使用""时都会创建一个新字符串。这不是真的——由于字符串实习,它将在每个程序集或每个AppDomain创建一次(或者可能在整个过程中创建一次——在这方面不确定)。这种差异可以忽略不计——很大程度上,大规模微不足道。
但是,你觉得哪个更具可读性是另一回事。它是主观的,因人而异——所以我建议你找出你的团队中大多数人喜欢什么,为了一致性,所有人都这样做。就我个人而言,我觉得0更容易阅读。
""和" "很容易被误认为对方的论点并没有真正被我所接受。除非您使用比例字体(并且我没有与任何开发人员合作过),否则很容易分辨出区别。
" "
虽然差异非常非常小,但差异仍然存在。
""创建了一个对象,而String.Empty没有。但是这个对象将被创建一次,如果代码中还有另一个"",稍后将从字符串池中引用。
String和string是相同的,但我建议使用String.Empty(以及String.Format、String.Copy等),因为点符号表示类,而不是运算符,并且类以大写字母开头符合C#编码标准。
String.Format
String.Copy
除了其他原因,我更喜欢字符串.空,以确保您知道它是什么,并且您没有意外删除内容,主要是为了国际化。如果我看到引号中的字符串,那么我总是不得不怀疑这是否是新代码,并且应该将其放入字符串表中。因此,每次代码更改/审查时,您都需要查找“引号中的内容”,是的,您可以过滤掉空字符串,但我告诉人们,除非您知道它不会本地化,否则永远不要将字符串放入引号中是一个好习惯。
几乎每个开发人员都会知道“”的意思。我第一次亲自遇到String.空,不得不花一些时间搜索谷歌以确定他们是否真的是完全相同的东西。
从性能和代码生成的角度来看,真的没有什么区别。在性能测试中,他们在哪个更快与另一个更快之间来回切换,并且只有毫秒。
在查看幕后代码时,你也看不到任何区别。唯一的区别是IL,它string.Empty使用操作码ldsfld""使用操作码ldstr,但这只是因为string.Empty是静态的,并且两个指令都做同样的事情。如果您查看生成的组件,则完全相同。
ldsfld
ldstr
private void Test1(){string test1 = string.Empty;string test11 = test1;} private void Test2(){string test2 = "";string test22 = test2;}
.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.Empty或Int32.TryParse(...)或Double.Epsilon
Int32.TryParse(...)
Double.Epsilon
在声明新实例时,我总是使用C#关键字:int i = 0;或string foo = "bar";
int i = 0;
string foo = "bar";
我很少使用未声明的字符串文字,因为我喜欢能够扫描代码将它们组合成可重用的命名常量。编译器无论如何都会用文字替换常量,所以这更多的是一种避免魔法字符串/数字的方法,并通过名称赋予它们更多的意义。另外,更改值更容易。
一个区别是,如果你使用switch-case语法,你不能写case string.Empty:,因为它不是常量。你得到一个Compilation error : A constant value is expected
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.Empty或string.Empty或String.Empty…我的护理水平很低;-)
System.String.Empty
没有人提到在VisualStudio String中颜色编码与字符串不同。这对于易读性很重要。此外,小写通常用于vars和type,没什么大不了的,但String.空是一个常量,而不是var或type。
我更喜欢string.Empty而不是String.Empty,因为您可以使用它而无需在文件中包含using System;。
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}
这表明所有三个变量,即str1、str2和str3,尽管使用不同的语法初始化,但都指向内存中相同的字符串(零长度)对象。
str1
str2
str3
所以在内部它们没有区别。这一切都归结为您或您的团队想要使用哪一个的便利性。字符串类的这种行为在. NET Framework中被称为字符串实习。Eric Lippert有一个非常好的博客这里描述了这个概念。
我只是在看一些代码,这个问题突然出现在我的脑海中,我以前读过一段时间。这当然是一个易读性的问题。
考虑以下C#代码…
(customer == null) ? "" : customer.Name
vs
(customer == null) ? string.empty : customer.Name
我个人认为后者不那么模棱两可,更容易阅读。
正如其他人所指出的,实际差异可以忽略不计。
我亲眼目睹了""两次导致(小)问题。一次是由于一个刚接触基于团队的编程的初级开发人员的错误,另一次是一个简单的错字,但事实是使用string.Empty本可以避免这两个问题。
是的,这在很大程度上是一个判断,但是当一种语言为您提供多种做事方式时,我倾向于倾向于具有最多编译器监督和最强编译时强制执行的语言。那就是没有""。这一切都是为了表达特定的意图。
如果你键入string.EMpty或Strng.Empty,编译器会让你知道你做到了错误。立即。它根本不会编译。作为开发人员,你引用特定的意图是编译器(或其他开发人员)不能以任何方式误解,当你做错了,你不能创建bug。
string.EMpty
Strng.Empty
如果您在表示""时键入" ",反之亦然,编译器会很乐意按照您的要求进行。另一个开发人员可能无法收集您的特定意图。创建的错误。
早在string.Empty出现之前,我就使用了定义EMPTY_STRING常量的标准库。我们仍然在案件语句中使用该常量在哪里string.Empty是不允许。
EMPTY_STRING
只要有可能,让编译器为你工作,并消除人为错误的可能性,无论多小。在我看来,这胜过其他人引用的“易读性”。
特异性和编译时执行。这就是晚餐的内容。
我使用“”是因为它在我的代码中会被明显地涂成黄色……出于某种原因,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愚弄某人。
""
"\u200D"