在我们的一个应用程序中,我遇到过这样的一些行:
Console.WriteLine(string.Empty);
如果我写的话,我检查了它是否有任何区别:
Console.WriteLine();
但输出是相同的(如预期的那样)。
什么"最佳实践"在这个例子中?是否有必要传递空string
而不是传递任何参数?
答案 0 :(得分:8)
WriteLine()
的实现方式如下:
public virtual void WriteLine() {
Write(CoreNewLine);
}
然而 WriteLine(string)
实现如下:
public virtual void WriteLine(String value) {
if (value==null) {
WriteLine();
}
else {
// We'd ideally like WriteLine to be atomic, in that one call
// to WriteLine equals one call to the OS (ie, so writing to
// console while simultaneously calling printf will guarantee we
// write out a string and new line chars, without any interference).
// Additionally, we need to call ToCharArray on Strings anyways,
// so allocating a char[] here isn't any worse than what we were
// doing anyways. We do reduce the number of calls to the
// backing store this way, potentially.
int vLen = value.Length;
int nlLen = CoreNewLine.Length;
char[] chars = new char[vLen+nlLen];
value.CopyTo(0, chars, 0, vLen);
// CoreNewLine will almost always be 2 chars, and possibly 1.
if (nlLen == 2) {
chars[vLen] = CoreNewLine[0];
chars[vLen+1] = CoreNewLine[1];
}
else if (nlLen == 1)
chars[vLen] = CoreNewLine[0];
else
Buffer.InternalBlockCopy(CoreNewLine, 0, chars, vLen * 2, nlLen * 2);
Write(chars, 0, vLen + nlLen);
}
}
如果使用null
字符串调用它,则会得到与没有参数的WriteLine()
相同的结果(以及另外的方法调用)。但是,传递非空字符串时的逻辑有点复杂。
对于string.Empty
,这将分配一个长度为2的新字符数组,并将新行字符复制到该字符数组。
这通常不贵,但如果您不想打印任何东西,仍然有点多余。特别是对于固定来电Console.WriteLine
,将string.Empty
传递给那里是没有意义的。
如果仅为了简单起见,您应该更喜欢Console.WriteLine()
而不是Console.WriteLine(string.Empty)
。
答案 1 :(得分:3)
最佳做法是使用更具可读性的blur
。
即使没有语义上的差异,如果你写Console.WriteLine();
,你也会执行unnecessary code:
Console.WriteLine(string.Empty);
那里有缓冲区分配和字符串复制。如果他们写了public virtual void WriteLine(String value) {
if (value==null) {
WriteLine();
}
else {
// We'd ideally like WriteLine to be atomic, in that one call
// to WriteLine equals one call to the OS (ie, so writing to
// console while simultaneously calling printf will guarantee we
// write out a string and new line chars, without any interference).
// Additionally, we need to call ToCharArray on Strings anyways,
// so allocating a char[] here isn't any worse than what we were
// doing anyways. We do reduce the number of calls to the
// backing store this way, potentially.
int vLen = value.Length;
int nlLen = CoreNewLine.Length;
char[] chars = new char[vLen+nlLen];
value.CopyTo(0, chars, 0, vLen);
// CoreNewLine will almost always be 2 chars, and possibly 1.
if (nlLen == 2) {
chars[vLen] = CoreNewLine[0];
chars[vLen+1] = CoreNewLine[1];
}
else if (nlLen == 1)
chars[vLen] = CoreNewLine[0];
else
Buffer.InternalBlockCopy(CoreNewLine, 0, chars, vLen * 2, nlLen * 2);
Write(chars, 0, vLen + nlLen);
}
/*
Write(value); // We could call Write(String) on StreamWriter...
WriteLine();
*/
}
会更好但是由于某种原因他们没有。
而更简单的方式is just:
if (string.IsNullOrEmpty(value))
(public virtual void WriteLine() {
Write(CoreNewLine);
}
是CoreNewLine
)
答案 2 :(得分:1)
技术方面对我没有任何区别。这只是开发人员觉得它舒适且可读性更强的方式。对我来说,Console.WriteLine()
更直观,它正在写一个空行,而Console.WriteLine(String.Empty)
让我停下来思考一下(也许更少)。
任何其他变体都是,IMO,这是一种使代码更加精美而不能用于专业生产代码的行为。
答案 3 :(得分:1)
来自参考(https://msdn.microsoft.com/en-us/library/system.console.writeline(v=vs.110).aspx)
WriteLine(String): 将指定的字符串值(后跟当前行终止符)写入标准输出流。
WriteLine(): 将当前行终止符写入标准输出流。
它似乎绝对没有(视觉)差异(实现,因为另一个答案提到的是另一个问题)并且将取决于用户偏好,尽管我不确定我知道很多人喜欢不必要的代码
答案 4 :(得分:1)
正如您在tryroslyn
上看到的那样C#代码:
using System;
public class C {
public void M() {
Console.WriteLine();
Console.WriteLine(String.Empty);
}
}
生成IL代码:
.class private auto ansi '<Module>'
{
} // end of class <Module>
.class public auto ansi beforefieldinit C
extends [mscorlib]System.Object
{
// Methods
.method public hidebysig
instance void M () cil managed
{
// Method begins at RVA 0x2050
// Code size 19 (0x13)
.maxstack 8
IL_0000: nop
IL_0001: call void [mscorlib]System.Console::WriteLine()
IL_0006: nop
IL_0007: ldsfld string [mscorlib]System.String::Empty
IL_000c: call void [mscorlib]System.Console::WriteLine(string)
IL_0011: nop
IL_0012: ret
} // end of method C::M
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2064
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method C::.ctor
} // end of class C
因此,行Console.WriteLine(String.Empty);
从string.Empty
获取值并将其传递给函数。更好的是Console.WriteLine()
次操作。