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

时间:2008-11-04 19:49:03

标签: c# .net string initialization

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

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

string willi = string.Empty;

string willi = String.Empty;

string willi = "";

或者什么?

31 个答案:

答案 0 :(得分:763)

使用您和您的团队最易读的内容。

其他答案表明,每次使用""时都会创建一个新字符串。这不是真的 - 由于字符串实习,它将在每个程序集创建一次或每个AppDomain创建一次(或者可能在整个过程中创建一次 - 在前面不确定)。这种差异可以忽略不计 - 大规模,大量无关紧要。

然而,

您发现更具可读性是另一回事。它是主观的,因人而异 - 所以我建议你找出你团队中大多数人都喜欢的东西,并且所有人都认为这是为了保持一致性。我个人认为""更容易阅读。

""" "容易被误认为的论点并没有真正与我相提并论。除非你使用比例字体(我没有使用任何开发人员),否则很容易区分。

答案 1 :(得分:369)

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

在查看幕后代码时,你真的看不出任何区别。唯一的区别在于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 void 
          Test1() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test1,
                [1] string test11)
  IL_0000:  nop
  IL_0001:  ldsfld     string [mscorlib]System.String::Empty
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test1
.method private hidebysig instance void 
        Test2() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test2,
                [1] string test22)
  IL_0000:  nop
  IL_0001:  ldstr      ""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_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 

答案 2 :(得分:75)

The best code is no code at all

  

编码的基本性质是,作为程序员,我们的任务是认识到我们做出的每一个决定都是权衡。 [...] 从简洁开始。根据测试要求增加其他尺寸。

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

答案 3 :(得分:51)

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

请查看此链接以获取更多信息: string-empty-versus-empty-quotes

答案 4 :(得分:42)

我更喜欢stringString。选择string.Empty超过""是选择一个并坚持下去的问题。使用string.Empty的好处是,您的意思非常明显,并且您不会意外地复制"\x003"中不可打印的字符,例如""

答案 5 :(得分:22)

我不打算进入,但我看到一些错误的信息被扔到这里。

我个人更喜欢string.Empty。这是个人偏好,我会根据具体情况与任何团队的意愿保持一致。

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

此外,这是一个鲜为人知的事实,使用“”是完全可以接受的。在其他环境中,“”的每个实例都将创建一个对象。但是,.NET会中断其字符串,因此将来的实例将从实际池中提取相同的不可变字符串,并且任何性能损失都可以忽略不计。来源:Brad Abrams

答案 6 :(得分:15)

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

答案 7 :(得分:13)

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

""而言,我不太确定。

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

答案 8 :(得分:10)

几乎每个开发人员都会知道“”的意思。我个人第一次遇到String.Empty,不得不花一些时间搜索谷歌,弄清楚他们是否真的 完全一样。

答案 9 :(得分:9)

这个主题非常古老而且很长,所以如果在其他地方提到这种行为,请原谅。 (并指出我的答案)

如果您使用string.Empty或双引号,我发现编译器的行为有所不同。如果您不使用使用string.Empty或双引号初始化的字符串变量,则会显示差异。

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

CS0219 - The variable 'x' is assigned but its value is never used
在使用双引号进行初始化的情况下,

永远不会被发出,您将获得预期的消息。

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

基本上,如果我做对了,他们希望允许程序员设置一个带有函数返回值的变量用于调试目的,而不会给他带来警告信息,因此只有在进行了大量的分配时才会限制警告和string.Empty不是常量而是字段。

答案 10 :(得分:8)

我在控制台应用程序中使用以下方法执行了这个非常简单的测试:

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

这清楚地表明,尽管使用不同的语法初始化所有三个变量即str1str2str3,但它们指向内存中完全相同的字符串(零长度)对象。我在.NET 4.5控制台应用程序中执行了此测试。所以内部他们没有区别,这一切都归结为你想用作程序员的方便性。字符串类的这种行为在.NET中称为 string interning 。 Eric Lippert有一个非常好的博客here来描述这个概念。

答案 11 :(得分:7)

以上任何一种。

有许多更好的事情需要教导。比如什么颜色的树皮最适合树,我认为模糊的棕色与青苔的色泽。

答案 12 :(得分:7)

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

答案 13 :(得分:6)

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

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

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

stringString之间我更喜欢小写string,因为我多年来一直使用Delphi而且Delphi样式是小写的string

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

答案 14 :(得分:6)

没有人提到在VisualStudio中字符串的颜色编码与字符串不同。这对可读性很重要。此外,小写通常用于变量和类型,但不是很大,但String.Empty是常量而不是var或类型。

答案 15 :(得分:5)

我没有任何区别。最后一个是键入最快的:)

答案 16 :(得分:4)

没关系 - 它们完全是一回事。 但是,主要的是你必须一致

P.S。我一直在为这种“什么是正确的东西”而斗争。

答案 17 :(得分:4)

这完全是一种代码风格的偏好,可以解决.NET如何处理字符串的问题。但是,这是我的意见:))

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

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

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

答案 18 :(得分:4)

我赞成string.Empty超过String.Empty,因为您无需在文件中加入using System;就可以使用它。

至于挑选""超过string.Empty,这是个人偏好,应由您的团队决定。

答案 19 :(得分:3)

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

[编辑]

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

答案 20 :(得分:3)

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

答案 21 :(得分:3)

我亲眼目睹了#34;"导致(次要)问题两次。曾经是由于一个初级开发人员错误的基于团队的编程,另一个是一个简单的错字,但事实是使用string.Empty会避免这两个问题。

是的,这是一个非常多的判断调用,但是当一种语言为您提供多种方法时,我倾向于倾向于编译时监督最多且编译时强制最强的那种。那是""。这完全是为了表达具体的意图。

如果键入string.EMpty或Strng.Empty,编译器会让您知道自己做错了。立即。它根本不会编译。作为开发人员,您引用特定的意图,编译器(或其他开发人员)无法以任何方式误解,并且当您做错时,您无法创建错误。

如果您键入" "当你的意思是""反之亦然,编译器很乐意做你告诉它做的事情。另一位开发人员可能会或可能不会收集您的具体意图。已创建错误。

在string.Empty之前很久我就使用了定义EMPTY_STRING常量的标准库。我们仍然在不允许使用string.Empty的case语句中使用该常量。

尽可能让编译器为您工作,并消除人为错误的可能性,无论多小。国际海事组织,这胜过可读性"正如其他人所引用的那样。

特异性和编译时执行。这是晚餐的原因。

答案 22 :(得分:2)

从长远来看,编译器应该使它们完全相同。选择一个标准,以便您的代码易于阅读,并坚持使用。

答案 23 :(得分:2)

我只是在查看一些代码,这个问题突然出现在我脑海中,我之前读过这篇文章。这当然是一个可读性问题。

考虑以下C#代码......

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

VS

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

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

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

答案 24 :(得分:2)

我用""因为它会在我的代码中以鲜明的黄色着色......由于某种原因,String.Empty在我的Visual Studio Code主题中都是白色的。而且我认为这对我最重要。

答案 25 :(得分:1)

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

答案 26 :(得分:1)

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

  

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

答案 27 :(得分:1)

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

答案 28 :(得分:0)

可能是一个有争议的评论,但是,总的来说,我发现与Microsoft保持一致可以使我的生活更轻松。我们可能不知道它们为什么会做事的全部深层原因(有时我认为很严格,有时很笨拙)。

他们在自动生成的文件(例如Assembly文件)中使用“”,这就是我要做的。实际上,当我尝试用String.Empty替换“”下面的任何内容时,Visual Studio崩溃了。对此可能有一个合乎逻辑的解释,但据我所知,如果我只是按照他们的意愿去做,大多数情况下事情就可以解决了。 (相反:我知道他们有些自动生成的文件也使用String.Empty,这打破了我的观点。:))

<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("")>

答案 29 :(得分:0)

我更喜欢"",因为它更短并且String.Empty解决了不存在的问题。

答案 30 :(得分:0)

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

1)“”创建对象,而String.Empty则不创建对象。但是这个对象将被创建一次,如果代码中有另一个“”,将在稍后从字符串池中引用。

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