Console.Writeline基础知识

我对以下代码有疑问:

class CurrentDate { static void Main() { Console.WriteLine(DateTime.Now); } } 

文件说:

使用指定的格式信息将指定对象数组的文本表示forms(后跟当前行终止符)写入标准输出流。

所以我的问题是: WriteLine如何知道DateTime对象的文本表示? 我的意思是,如果我从我自己的类创建自己的对象,它将如何知道如何将值转换为文本? 甚至更多,它如何知道价值是什么? 如何定义对象的“值”?

WriteLine怎么知道DateTime对象的文本表示? 我的意思是,如果我从我自己的类创建自己的对象,它将如何知道如何将值转换为文本?

Console.WriteLine有一组匹配特定类型(主要是基元) 的重载 。 如果编译器与提供的类型的重载不匹配,则它与重载System.Object (授予您提供单个参数)匹配。 如果发生这种情况,它会检查类型是否实现IFormattable ,如果是,则调用IFormattable.ToString(null, Formatter) 。 如果没有,它会在您的对象上调用ToStringToStringSystem.Object定义,所有对象都inheritance自。 每个想要自定义表示的对象都会覆盖默认行为,就像DateTime那样。

例如,假设您有一个带有Bar字符串属性的Foo类,并且您希望Console.WriteLine在将Foo传递给它时打印有意义的内容:

 public class Foo { public string Bar { get; set; } public override string ToString() { return Bar; } } 

现在我们要传递它Console.WriteLine

 public static void Main(string[] args) { var foo = new Foo { Bar = "bar" }; Console.WriteLine(foo); } 

会产生“酒吧”。

由于Console.WriteLine(DateTime)没有重载,因此调用Console.WriteLine(Object)重载并且此重载调用 TextWriter.WriteLine(object)重载 ,该重载 实现为 :

 IFormattable f = value as IFormattable; if (f != null) WriteLine(f.ToString(null, FormatProvider)); else WriteLine(value.ToString()); 

如您所见,此方法检查此对象类型是否实现IFormattable接口 。 由于Datetime实现了此接口 ,因此将f.ToString(null, FormatProvider) 。 从这个方法的文档中 ,第一个参数是:

空引用(在Visual Basic中为Nothing),以使用为IFormattable实现的类型定义默认格式

并从DateTime.ToString(String, IFormatProvider)方法的文档:

如果format为null或空字符串(“”),则使用标准格式说明符"G"

这意味着,该表示将是属于您的CurrentCultureShortDatePatternLongTimePattern属性的组合

如果需要自定义类的特殊格式,可以覆盖类型的.ToString()方法以更改其行为。

与某些人的想法相反, 不会调用DateTime.ToString() 。 在.NET中,对象可以有两种方法来“串行化”自身:覆盖string Object.ToString()方法并实现IFormattable接口。 DateTime同时执行。

现在……当你尝试做的时候

 Console.WriteLine(DateTime.Now); 

选择void public static void WriteLine(Object value)重载(如果在Visual Studio中按Ctrl +单击WriteLine ,则可以看到它)。 此方法只调用TextWriter.WriteLine(value)方法,该方法:

 IFormattable f = value as IFormattable; if (f != null) WriteLine(f.ToString(null, FormatProvider)); else WriteLine(value.ToString()); 

所有这些都可以通过ILSpy轻松查看并查找Console.WriteLine