[英]In C#, should I use string.Empty or String.Empty or "" to intitialize a string?
在C#中,我想用一个空字符串初始化一个字符串值。
我应该怎么做? 什么是正确的方法,为什么?
string willi = string.Empty;
要么
string willi = String.Empty;
要么
string willi = "";
或者是什么?
使用您和您的团队认为最具可读性的任何内容。
其他答案建议每次使用""
时都会创建一个新字符串。 这不是真的 - 由于字符串实习,它将在每个程序集或每个 AppDomain 中创建一次(或者可能在整个过程中创建一次 - 在这方面不确定)。 这种差异可以忽略不计-大规模,大量微不足道。
但是,您发现哪个更具可读性是另一回事。 这是主观的,会因人而异——所以我建议你找出你团队中大多数人喜欢什么,然后为了一致性而一致。 我个人觉得""
更容易阅读。
""
和" "
很容易被误认为是彼此的论点并没有真正让我感到满意。 除非您使用的是比例字体(我还没有与任何这样做的开发人员合作过),否则很容易区分。
从性能和代码生成的角度来看,确实没有区别。 在性能测试中,他们在哪个更快与另一个之间来回切换,并且仅相差几毫秒。
在查看幕后代码时,您也确实看不出任何区别。 唯一的区别是在 IL 中,其中string.Empty
使用操作码ldsfld
而""
使用操作码ldstr
,但这只是因为string.Empty
是静态的,并且两个指令都执行相同的操作。 如果您查看生产的组件,它是完全相同的。
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
.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
编码的基本性质是,作为程序员,我们的任务是认识到我们所做的每一个决定都是一种权衡。 [...]从简洁开始。 根据测试需要增加其他尺寸。
因此,代码越少越好:比string.Empty
或String.Empty
更喜欢""
。 这两个长六倍,没有额外的好处——当然没有增加清晰度,因为它们表达了完全相同的信息。
一个区别是,如果您使用switch-case
语法,则不能编写case string.Empty:
因为它不是常量。 你得到一个Compilation error : A constant value is expected
查看此链接了解更多信息: string-empty-versus-empty-quotes
我更喜欢string
而不是String
。 选择string.Empty
不是""
是选择一个并坚持下去的问题。 使用string.Empty
优点是您的意思非常明显,并且您不会意外地复制"\\x003"
中的""
"\\x003"
等不可打印字符。
我不打算插话,但我看到一些错误的信息在这里被抛出。
我个人更喜欢string.Empty
。 这是个人偏好,我会根据具体情况服从与我合作的任何团队的意愿。
正如其他一些人所提到的, string.Empty
和String.Empty
之间根本没有区别。
此外,这是一个鲜为人知的事实,使用 "" 是完全可以接受的。 在其他环境中,"" 的每个实例都会创建一个对象。 但是,.NET 实习其字符串,因此未来的实例将从实习池中提取相同的不可变字符串,并且任何性能损失都可以忽略不计。 资料来源:布拉德艾布拉姆斯。
我个人更喜欢 "" 除非有充分的理由来处理更复杂的事情。
String.Empty
和string.Empty
是等价的。 String
是 BCL 类名; string
是它的 C# 别名(或快捷方式,如果你愿意的话)。 与Int32
和int
相同。 有关更多示例,请参阅文档。
至于""
,我不太确定。
就个人而言,我总是使用string.Empty
。
我在控制台应用程序中使用以下方法执行了这个非常简单的测试:
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
}
这清楚地表明,所有三个变量,即str1
、 str2
和str3
尽管使用不同的语法初始化,但都指向内存中完全相同的字符串(零长度)对象。 我在 .NET 4.5 控制台应用程序中执行了这个测试。 所以在内部它们没有区别,这一切都归结为您想作为程序员使用哪一个的便利性。 字符串类的这种行为在 .NET 中称为字符串实习。 Eric Lippert 有一个非常好的博客在这里描述了这个概念。
几乎每个开发人员都知道“”是什么意思。 我个人第一次遇到 String.Empty 并且不得不花一些时间在 google 上搜索以确定它们是否真的是完全相同的东西。
这个话题很老而且很长,所以如果在其他地方提到了这种行为,请原谅。 (并指出我的答案,涵盖了这一点)
如果您使用string.Empty
或双引号,我发现编译器的行为会有所不同。 如果您不使用用 string.Empty 或双引号初始化的字符串变量,差异就会显现出来。
如果使用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
基本上,如果我做对了,他们希望允许程序员设置一个带有函数返回值的变量以用于调试目的,而不会用警告消息打扰他,因此他们只在持续赋值和字符串的情况下限制了警告。 Empty 不是常量而是一个字段。
没有人提到在 VisualStudio 中字符串的颜色编码与字符串不同。 这对可读性很重要。 此外,小写通常用于 vars 和 type,没什么大不了的,但 String.Empty 是一个常量而不是 var 或类型。
以上任何一项。
有很多很多更好的事情需要宣扬。 比如什么颜色的树皮最适合树,我认为是带有淡淡苔藓的模糊棕色。
我非常喜欢 String.Empty,除了确保您知道它是什么以及您没有意外删除内容的其他原因之外,主要是为了国际化。 如果我在引号中看到一个字符串,那么我总是想知道这是否是新代码,是否应该将其放入字符串表中。 因此,每次更改/审查代码时,您都需要查找“引号中的内容”,是的,您可以过滤掉空字符串,但我告诉人们最好不要将字符串放在引号中,除非您知道它不会被本地化.
string
是System.String
类型的同义词,它们是相同的。
值也相同: string.Empty == String.Empty == ""
我不会在代码中使用字符常量 "",而是使用string.Empty
或String.Empty
- 更容易理解程序员的意思。
在string
和String
之间,我更喜欢小写string
,因为我曾经使用 Delphi 工作了很多年,而 Delphi 风格是小写string
。
所以,如果我是你的老板,你会写string.Empty
我更喜欢string.Empty
不是String.Empty
因为你可以使用它而无需包含using System;
在您的文件中。
至于选择""
不是string.Empty
,这是个人喜好,应该由您的团队决定。
我没有任何区别。 最后一个是最快的输入:)
这完全是一种代码风格的偏好,是关于 .NET 如何处理字符串的。 但是,这是我的意见:)
在访问静态方法、属性和字段时,我总是使用 BCL 类型名称: String.Empty
或Int32.TryParse(...)
或Double.Epsilon
我在声明新实例时总是使用 C# 关键字: int i = 0;
或string foo = "bar";
我很少使用未声明的字符串文字,因为我喜欢能够扫描代码将它们组合成可重用的命名常量。 编译器无论如何都会用文字替换常量,因此这更像是一种避免魔术字符串/数字并通过名称赋予它们更多含义的方法。 此外,更改值更容易。
没关系 - 它们是完全一样的。 然而,最重要的是你必须保持一致
ps我一直在为这种“什么是正确的事情”而挣扎。
我亲眼目睹了两次导致(小)问题的“”。 一次是由于初级开发人员对基于团队的编程不熟悉,另一个是简单的错字,但事实是使用 string.Empty 可以避免这两个问题。
是的,这在很大程度上是一种判断,但是当一种语言为您提供多种做事方式时,我倾向于倾向于具有最多编译器监督和最强编译时强制执行的语言。 那不是“”。 一切都是为了表达特定的意图。
如果您键入 string.EMpty 或 Strng.Empty,编译器会让您知道您做错了。 立即地。 它根本不会编译。 作为开发人员,您引用了编译器(或其他开发人员)不能以任何方式误解的特定意图,并且当您做错时,您无法创建错误。
如果您在表示“”时键入“”,反之亦然,编译器会很高兴地按照您的要求执行。 其他开发人员可能会也可能不会收集您的特定意图。 错误创建。
早在 string.Empty 之前,我就使用了定义 EMPTY_STRING 常量的标准库。 我们仍然在不允许 string.Empty 的 case 语句中使用该常量。
只要有可能,就让编译器为您工作,并消除人为错误的可能性,无论多么小。 IMO,正如其他人所引用的那样,这胜过“可读性”。
特异性和编译时强制执行。 这是晚餐吃的。
我使用第三个,但在其他两个中,第一个似乎不那么奇怪。 string 是 String 的别名,但是在作业中看到它们感觉很不舒服。
前两者中的任何一个对我来说都是可以接受的。 我会避免使用最后一个,因为通过在引号之间放置一个空格来引入错误相对容易。 通过观察很难发现这个特定的错误。 假设没有错别字,所有在语义上都是等价的。
[编辑]
此外,您可能希望始终使用string
或String
以保持一致性,但这只是我。
我使用 "" 是因为它在我的代码中会被着色成明显的黄色......出于某种原因,String.Empty 在我的 Visual Studio Code 主题中全是白色的。 我相信这对我来说是最重要的。
从长远来看,编译器应该使它们完全相同。 选择一个标准,以便您的代码易于阅读,并坚持下去。
我只是在看一些代码,这个问题突然出现在我的脑海中,我之前看过这个问题。 这当然是可读性的问题。
考虑以下 C# 代码...
(customer == null) ? "" : customer.Name
对比
(customer == null) ? string.empty : customer.Name
我个人认为后者不那么模棱两可,更容易阅读。
正如其他人所指出的,实际差异可以忽略不计。
我认为第二个是“适当的”,但老实说,我认为这无关紧要。 编译器应该足够聪明,可以将其中任何一个编译为完全相同的字节码。 我自己用“”。
虽然差异非常非常小,但差异仍然存在。
1) "" 创建对象,而 String.Empty 不会。 但是这个对象将被创建一次,如果代码中有另一个“”,稍后将从字符串池中引用。
2) String 和 string 相同,但我建议使用 String.Empty(以及 String.Format、String.Copy 等),因为点符号表示类,而不是运算符,并且类以大写字母开头符合C# 编码标准。
空字符串就像空集,只是每个人都用来称呼""
。 同样在正式语言中,由长度为零的字母表创建的字符串称为空字符串。 set 和 string 都有一个特殊的符号。 空串:ε 和空集:∅。 如果你想谈论这个零长度的字符串,你会称它为空字符串,这样每个人都知道你指的是什么。 现在,如果您将其命名为空字符串,为什么不在代码中使用string.Empty
,它的意图是明确的。 缺点是它不是一个常数,因此在任何地方都不可用,就像在属性中一样。 (由于某些技术原因,它不是常数,请参阅参考资料。)
在http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx 上:
正如大卫所暗示的那样,
String.Empty
和""
之间的差异非常小,但还是有区别的。""
实际上创建了一个对象,它可能会被从字符串实习池中拉出,但仍然......而String.Empty
创建任何对象......所以如果你真的在寻找最终的内存效率,我建议使用String.Empty
。 但是,您应该记住,差异是如此微不足道,您可能永远不会在代码中看到它......
至于System.String.Empty
或string.Empty
或String.Empty
......我的护理水平很低;-)
我更喜欢""
因为它更短,并且String.Empty
解决了不存在的问题。
可能是一个有争议的评论,但总的来说,我发现当我与 Microsoft 一致行动时,我的生活会更轻松。 我们不可能知道他们做事的全部深层原因(有时非常严格,有时我认为有时很笨拙)。
他们在诸如程序集文件之类的自动生成的文件中使用“”,这就是我所做的。 事实上,当我尝试用 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("")>
如果您想恶作剧某人,请将""
放入他们的代码中。 这不是空字符串,它是""
。 你不能用string.Empty
来愚弄别人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.