浅析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默认值为"\r\n"

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

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

switch (num2)  //确定CoreNewLine的值是 "\n"(num2==1) 还是 "\r\n"(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()的功能是输出一个字符或字符串并换行,其实现考虑到了各个方面,包括功能的细化,精密的组织,鲜明的层次等。

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

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

时间: 2024-10-14 06:47:38

浅析System.Console.WriteLine()的相关文章

C#中System.Console.WriteLine()输出多个参数

<C#入门经典(第五版)>中第3章 变量与表达式 中提到System.Console.WriteLine({0},{1},myString,myInteger);输出多个参数时,"每个占位符用一对{ }中加一个整数来表示.整数从0开始,每次递增1,占位符的总数应等于列表中指定的变量数,该列表用逗号分隔开,跟在字符串后面." 实际上只要占位符的第1个整数为0就可以,其他整数小于变量总数就可以,不必每次递增1,也不必占位符的个数和变量的个数相等,但是占位符中的整数代表了变量列表

C#中Console.WriteLine()函数输出格式详解

格式项都采用如下形式: {index[,alignment][:formatString]} 其中"index"指索引占位符,这个肯定都知道: ",alignment"按字面意思显然是对齐方式,以","为标记: ":formatString"就是对输出格式的限定,以":"为标记. alignment:可选,是一个带符号的整数,指示首选的格式化字段宽度.如果“对齐”值小于格式化字符串的长度,“对齐”会被忽略,

C#总结(1)-从抚摸“Console.WriteLine”开始的逐渐深入

看笔记上的时间是在2016.2.5号开始学习C#语言的,直至今天不到一个月的时间,跟培养计划上比,足足慢了一 半,也是够”呵呵“的了,乐观点,要把基础打好: 从这篇博客开始总结这段时间C#的学习,时间问题,只能每天一点,断断续续的进行了. 初识: 此阶段可以说是零基础认识期间,知道了C#仅仅是一种编程语言,需要".Net\Dotnet"这样的一种平台,一种技术,此外还得需要一个合适的"IDE"比如"Visual Studio 2012"这样的软件

第一个输出程序 Console.WriteLine

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace _01个程序{ class Program { static void Main(string[] args) { Console.WriteLine("************************"); // WriteLine输出字符并将

C#里面Console.Write()和Console.WriteLine()有什么区别?

Console.Write()和Console.WriteLine()都是System.Console提供的方法,两着主要用来将输出流由指定的输出装置(默认为屏幕)显示出来.两着间的差异在Console.WriteLine()方法是将要输出的字符串与换行控制字符一起输出,当次语句执行完毕时,光标会移到目前输出字符串的下一行.至于Console.Write()方法,光标会停在输出字符串的最后一个字符后,不会移动到下一行.比如说Console.WriteLine("a");Console.

C#核编之System.Console类

顾名思义,Console类封装了基于控制台的输入输出和错误流的操作,下面列举一些System.Console类常用的成员的,这些成员能为简单的命令行程序添加一些"情趣",例如改变背景颜色和前景颜色,以各种频率发出峰鸣声.代码如下: //Console.Beep(666, 6000);//让控制台以各种频率发出峰鸣声 Console.BackgroundColor = ConsoleColor.Green;//控制台输入行的背景颜色 Console.ForegroundColor = C

WriteLine(ls.ToString());Console.WriteLine(ls);输出结果相同,为什么要加 .ToString()

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Test05 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 int shj1 = 45; //声明整型变量shj1,并赋值为45 13 int shj2 = 5; //声明整型变量shj2,并赋值

VS2015使用技巧 为什么我们可以输入cw后按两下tab键出现console.writeline

因为代码段的存在.那么如何查看代码段都有啥呢? 1. 2. 3.存储cw的文件中写了啥? <?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> &l

C# Winform里面用Console.WriteLine输出到哪了

C# Winform里面用Console.WriteLine输出也不会报错 显示在 VS IDE 的视图→输出窗口,且只在 Debug 环境下此语句执行. 如果是 Release 环境,在 Win32 程序中 System.Console.System.Diagnostics.Debug.System.Diagnostics.Trace 是不执行的,这点可以从 IL 代码看出. 按照优先级来说 System.Diagnostics.Trace 高于 System.Diagnostics.Debu