浅析System.Console.WriteLine()

浅析System.Console.WriteLine()

    Writeline()函数的功能向 StreamWriter写入指定字符串和一行字符,共有19个重载,其与Write()函数的主要区别在于它输出字符串后换行,而Write()不换行。现在,通过WriteLine()的通用版本(即WriteLine(string format,object arg0,object arg1,object arg2,object arg3,__arglist))来深入理解其实现细节。

    首先,我们来看一下源代码:

[CLSCompliant(false), HostProtection(SecurityAction.LinkDemand, UI=true)

public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3, __arglist)

{

    ArgIterator iterator = new ArgIterator(__arglist);

    int num = iterator.GetRemainingCount() + 4;  //参数个数

    object[] arg = new object[num];    //参数集合

    arg[0] = arg0;

    arg[1] = arg1;

    arg[2] = arg2;

    arg[3] = arg3;

    for (int i = 4; i < num; i++)

    {

        arg[i] = TypedReference.ToObject(iterator.GetNextArg());

    }

    Out.WriteLine(format, arg);  

}

看函数签名可知,WriteLine()是一个静态的无返回值的有可变参数的函数。并通过TextWrite的一个静态对象(Out)的方法(Out.WriteLine())输出字符串。

(注:TextWrite是一个抽象类,无法实例化,所以Out实际上是StreamWrite类的一个实例的引用)

 

[__DynamicallyInvokable]

public virtual void WriteLine(string format, params object[] arg)

{

    this.WriteLine(string.Format(this.FormatProvider, format, arg));

}

 代码很简短,就是调用同一个对象的WriteLine() 的另一个重载,并使用String类的一个方法用参数替换字符串中相应的占位符,得到要输出的完整的字符串。

 

[__DynamicallyInvokable]

public virtual void WriteLine(string value)

{

    if (value == null)

    {

        this.WriteLine();

    }

    else

    {

        int length = value.Length;

        int num2 = this.CoreNewLine.Length;  //CoreNewLine默认值为" "

        char[] destination = new char[length + num2];  //包含换行符的字符串(目的字符串)

        value.CopyTo(0, destination, 0, length);

        switch (num2)  //确定CoreNewLine的值是 " "(num2==1) 还是 " "(num2==2)

        {

            case 2:

                destination[length] = this.CoreNewLine[0];

                destination[length + 1] = this.CoreNewLine[1];

                break;

 

            case 1:

                destination[length] = this.CoreNewLine[0];

                break;

 

            default:

                Buffer.InternalBlockCopy(this.CoreNewLine, 0, destination, length * 2, num2 * 2);

                break;

        }

        this.Write(destination, 0, length + num2);

    }

}

处理换行符并添加到字符串中,用Write()的一个重载输出。

 

 

[__DynamicallyInvokable]

public virtual void Write(char[] buffer, int index, int count)

{

    if (buffer == null)

    {

        throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));

    }

    if (index < 0)

    {

        throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));

    }

    if (count < 0)

    {

        throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));

    }

    if ((buffer.Length - index) < count)

    {

        throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));

    }

    for (int i = 0; i < count; i++)

    {

        this.Write(buffer[index + i]);

    }

}

 

从第一个字符开始检查字符串是否有异常,只有完全没异常后才调用Write()将最终的字符串输出(一个字符一个字符的输出)。

 

[__DynamicallyInvokable]
public override void Write(char value)
{
    this.CheckAsyncTaskInProgress();  //异步操作
    if (this.charPos == this.charLen)
    {
        this.Flush(false, false);
    }
    this.charBuffer[this.charPos] = value;
    this.charPos++;
    if (this.autoFlush)
    {
        this.Flush(true, false);
    }
}
注:TextWriter 类并没有实现此方法,Out对象调用的是StreamWriter 的一个实例,而 StreamWriter 继承自 TextWriter 并实现了此方法。

 

System.Console.WriteLine()的功能是输出一个字符或字符串并换行,其实现考虑到了各个方面,包括功能的细化,精密的组织,鲜明的层次等。

我们编程,不一定要向别人这样将一个类,一个方法写的这样有条理,但应当学习别人的编程的思想与代码的结构与组织方法等,并尽量向别人看齐,

这样,有助于我们在编程的时候构建一个清晰的代码体系和结构,提高编程效率与学习效率。

原文地址:https://www.cnblogs.com/SilentCode/p/4830879.html