关于.NET:在C#中,我应该使用string.empty还是String.empty或””初始化字符串?

In C#, should I use string.Empty or String.Empty or “” to intitialize a string?

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

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

1
string willi = string.Empty;

1
string willi = string.Empty;

1
string willi ="";

或者什么?


使用你和你的团队认为最可读的东西。

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

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

关于江户一号(0)和江户一号(3)很容易被误认为是对方的说法,我并不认同。除非你使用的是比例字体(我还没有和任何开发人员合作过),否则很容易分辨出不同之处。


从性能和代码生成的角度来看,确实没有什么不同。在性能测试中,它们来回切换,其中一个比另一个更快,而且仅以毫秒为单位。

在查看幕后代码时,您也没有看到任何区别。唯一的区别是IL,string.Empty使用操作码ldsfld。而""使用操作码ldstr,但这仅仅是因为string.Empty是静态的,两个指令都做同样的事情。如果您查看生成的程序集,它是完全相同的。

C码

1
2
3
4
5
6
7
8
9
10
11
private void Test1()
{
    string test1 = string.Empty;    
    string test11 = test1;
}

private void Test2()
{
    string test2 ="";    
    string test22 = test2;
}

IL码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.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

汇编代码

1
2
3
4
5
6
7
        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
1
2
3
4
5
6
7
        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


最好的代码是完全没有代码:

The fundamental nature of coding is that our task, as programmers, is to recognize that every decision we make is a trade-off. […] Start with brevity. Increase the other dimensions as required by testing.

因此,代码越少越好:倾向于""而不是string.Emptystring.Empty。这两种语言的使用时间长了六倍,没有额外的好处——当然没有额外的清晰性,因为它们表达的信息完全相同。


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

查看此链接了解更多信息:字符串空引号与空引号


我更喜欢string而不是string。选择string.Empty而不是""是选择并坚持的问题。使用string.Empty的好处在于,它非常明显地体现了您的意思,而且您不会意外地复制不可打印的字符,如"\x003"在您的""中。


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

我个人更喜欢string.Empty。这是我个人的偏好,我服从于我在个案基础上与之合作的任何团队的意愿。

正如其他一些人提到的,string.Emptystring.Empty之间完全没有区别。

此外,这是一个鲜为人知的事实,使用""是完全可以接受的。""的每个实例都将在其他环境中创建一个对象。然而,.NET将其字符串进行实习生,因此将来的实例将从实习生池中提取相同的不可变字符串,并且任何性能影响都可以忽略不计。资料来源:Brad Abrams。


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


string.Emptystring.Empty是等效的。string是bcl类名;string是其C别名(如果愿意,也可以是快捷键)。与Int32int相同。有关更多示例,请参阅文档。

至于"",我不太确定。

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


几乎所有开发人员都知道""的含义。我个人遇到了string.empty的第一次,不得不花一些时间搜索谷歌,看看他们是否真的是完全相同的事情。


这个话题已经很老了,很长时间了,如果在其他地方提到过这种行为,请原谅。(并指给我答案)

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

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

1
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

基本上,如果我做的对,他们希望允许程序员设置一个变量,函数的返回值用于调试,而不需要用警告消息打扰他,因此他们只在开销分配和字符串的情况下限制警告。空不是一个常量,而是一个字段。


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

1
2
3
4
5
6
7
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控制台应用程序中执行了此测试。所以在内部,它们没有区别,归根结底,它们都是为了方便您作为程序员使用。String类的这种行为称为在.NET中插入字符串。埃里克·利珀特在这里有一个非常好的博客描述了这个概念。


以上任何一种。

有许多更好的事情要自言自语。比如树皮什么颜色最适合一棵树,我认为模糊的棕色带有杜尔塞特苔藓的味道。


我非常喜欢字符串。空的,除了其他原因,以确保您知道它是什么,并且您没有意外地删除内容,但主要是为了国际化。如果我看到一个用引号括起来的字符串,那么我总是想知道这是否是一个新的代码,它应该被放入一个字符串表中。因此,每当代码被更改/审阅时,您需要查找"引号中的某些内容",是的,您可以过滤掉空字符串,但我告诉人们,最好不要在引号中添加字符串,除非您知道它不会本地化。


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


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

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

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

stringstring之间,我更喜欢小写的string,因为我在Delphi工作了很多年,Delphi样式是小写的string

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


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


它完全是一个代码样式的首选项,用于处理.NET如何处理字符串。但是,我的意见是:)

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

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

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


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

对于选择""而不是string.Empty,这是个人的偏好,应由您的团队决定。


没关系,它们是完全一样的。但是,最重要的是你必须保持一致

另外,我一直在和这种"什么是正确的事情"斗争。


我用第三个,但其他两个中第一个似乎不那么奇怪。字符串是字符串的别名,但在分配过程中看到它们会让人感觉不舒服。


我亲自目睹了""导致(小)问题两次。一次是由于一个新手对基于团队的编程的错误,另一次是一个简单的打字错误,但事实是使用了string.empty可以避免这两个问题。

是的,这在很大程度上是一种判断调用,但是当一种语言为您提供了多种方法来做事情时,我倾向于使用一种具有最多编译器监督和最强编译时强制的方法。这不是""。一切都是为了表达特定的意图。

如果您键入string.empty或strng.empty,编译器会让您知道您错了。立即。它只是无法编译。作为一个开发人员,您引用的是编译器(或其他开发人员)不能以任何方式曲解的特定意图,并且当您执行错误操作时,您不能创建bug。

如果您在"when you means"中键入"",或者反之亦然,编译器会很高兴地按照您的指示进行操作。另一个开发人员可能或可能无法了解您的特定意图。创建错误。

早在string.empty之前,我就用了一个标准库来定义空的字符串常量。在不允许使用string.empty的case语句中,仍然使用该常量。

只要有可能,让编译器为您工作,并消除人为错误的可能性,无论有多小。在我看来,这比其他人所说的"可读性"更重要。

特定性和编译时强制。这就是吃晚饭的原因。


前两个我都可以接受。我将避免最后一个错误,因为在引号之间加一个空格相对容易引入错误。通过观察很难发现这个特定的错误。假设没有错别字,所有的都在语义上是等价的。

[编辑]

另外,您可能希望始终使用stringstring来保持一致性,但这只是我自己。


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


我使用"",因为它将在我的代码中以独特的黄色显示…出于某种原因,在我的Visual Studio代码主题中,string.empty都是白色的。我相信这对我来说最重要。


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

考虑下面的C代码…

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

VS

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

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

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


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


我认为第二个是"合适的",但老实说,我认为这无关紧要。编译器应该足够聪明,能够将任何一个字节码编译成完全相同的字节码。我自己用。


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

As David implies, there difference between String.Empty and "" are pretty small, but there is a difference. "" actually creates an object, it will likely be pulled out of the string intern pool, but still... while String.Empty creates no object... so if you are really looking for ultimately in memory efficiency, I suggest String.Empty. However, you should keep in mind the difference is so trival you will like never see it in your code...
As for System.String.Empty or string.Empty or String.Empty... my care level is low ;-)


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

1)""在string.empty不创建对象。但此对象将创建一次,如果代码中还有其他"",则稍后将从字符串池引用此对象。

2)字符串和字符串是相同的,但我建议使用string.empty(以及string.format、string.copy等),因为点符号表示类,而不是运算符,并且以大写字母开头的类符合C编码标准。