Console.WriteLine()与Console.WriteLine(string.Empty)

时间:2016-07-18 09:00:03

标签: c#

在我们的一个应用程序中,我遇到过这样的一些行:

Console.WriteLine(string.Empty);

如果我写的话,我检查了它是否有任何区别:

Console.WriteLine();

但输出是相同的(如预期的那样)。

什么"最佳实践"在这个例子中?是否有必要传递空string而不是传递任何参数?

5 个答案:

答案 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()次操作。