简体   繁体   English

Console.Writeline基础知识

[英]Console.Writeline basics

I have a question about the following code: 我对以下代码有疑问:

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

Documentation says: 文件说:

Writes the text representation of the specified array of objects, followed by the current line terminator, to the standard output stream using the specified format information. 使用指定的格式信息将指定对象数组的文本表示形式(后跟当前行终止符)写入标准输出流。

So my question is: How come WriteLine knows the text representation of DateTime object? 所以我的问题是: WriteLine如何知道DateTime对象的文本表示? I mean, if I create my own object from my own class, how would it know how to convert the value to text? 我的意思是,如果我从我自己的类创建自己的对象,它将如何知道如何将值转换为文本? And even more, how does it know what the value is? 甚至更多,它如何知道价值是什么? How can you define "value" of an object? 如何定义对象的“值”?

How come WriteLine knows the text representation of DateTime object? WriteLine怎么知道DateTime对象的文本表示? I mean, if I create my own object from my own class, how would it know how to convert the value to text? 我的意思是,如果我从我自己的类创建自己的对象,它将如何知道如何将值转换为文本?

Console.WriteLine has a set of overloads matching specific types (mainly primitives). Console.WriteLine有一匹配特定类型(主要是基元) 的重载 If the compiler doesn't match an overload with the provided type, it matches with the overload taking System.Object (granted you provide a single parameter). 如果编译器与提供的类型的重载不匹配,则它与重载System.Object匹配(授予您提供单个参数)。 If that happens, it checks to see if the type implements IFormattable , if it does, it invokes IFormattable.ToString(null, Formatter) . 如果发生这种情况,它会检查类型是否实现IFormattable ,如果是,则调用IFormattable.ToString(null, Formatter) If it doesn't, it invokes ToString on your object. 如果没有,它会在您的对象上调用ToString ToString is defined in System.Object , which all objects inherit from. ToStringSystem.Object定义,所有对象都从该对象继承。 Every object that wants a custom representation overrides the default behavior, like DateTime does. 每个想要自定义表示的对象都会覆盖默认行为,就像DateTime一样。

For example, lets say you have a Foo class with a Bar string property, and you want Console.WriteLine to print something meaningful when passing your Foo to it: 例如,假设您有一个带有Bar字符串属性的Foo类,并且您希望Console.WriteLine在将Foo传递给它时打印有意义的内容:

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

And now we want to pass it Console.WriteLine : 现在我们要传递它Console.WriteLine

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

Would yield "bar". 会产生“酒吧”。

Since there is no overload for Console.WriteLine(DateTime) ,as in your case,the Console.WriteLine(Object) overload is called and this overload calls the TextWriter.WriteLine(object) overload which is implemented as : 由于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());

As you can see, this method checks if this object type implements IFormattable interface or not. 如您所见,此方法检查此对象类型是否实现IFormattable接口 Since Datetime implements this interface , your f.ToString(null, FormatProvider) will be called. 由于Datetime实现了此接口 ,因此将f.ToString(null, FormatProvider) From this method's documentation the first parameter is: 从这个方法的文档中 ,第一个参数是:

A null reference (Nothing in Visual Basic) to use the default format defined for the type of the IFormattable implementation . 空引用(在Visual Basic中为Nothing),以使用为IFormattable实现的类型定义默认格式

And from the DateTime.ToString(String, IFormatProvider) method's documentation: 并从DateTime.ToString(String, IFormatProvider)方法的文档:

If format is null or an empty string (""), the standard format specifier, "G" ., is used. 如果format为null或空字符串(“”),则使用标准格式说明符"G"

That means, the representation will be a combination of the ShortDatePattern and LongTimePattern properties belonging to your CurrentCulture 这意味着,该表示将是属于您的CurrentCultureShortDatePatternLongTimePattern属性的组合

If you want a special format for your custom class, you can override the .ToString() method of your type to change its behaviour. 如果需要自定义类的特殊格式,可以覆盖类型的.ToString()方法以更改其行为。

Contrary to what some persons think, DateTime.ToString() won't be called. 与某些人的想法相反, 不会调用DateTime.ToString() In .NET, an object can have two ways to "stringize" itself: overriding the string Object.ToString() method and implementing the IFormattable interface. 在.NET中,对象可以有两种方法来“自我”字符串化:覆盖string Object.ToString()方法并实现IFormattable接口。 DateTime does both. DateTime做到了。

Now... When you try doing 现在......当你尝试做的时候

Console.WriteLine(DateTime.Now);

the void public static void WriteLine(Object value) overload is selected (you can see it if you Ctrl+Click on WriteLine in Visual Studio). 选择void public static void WriteLine(Object value)重载(如果在Visual Studio中按Ctrl +单击WriteLine ,则可以看到它)。 This method simply calls the TextWriter.WriteLine(value) method, that does: 此方法只调用TextWriter.WriteLine(value)方法,该方法:

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

All of this can be easily seen using ILSpy and looking for the Console.WriteLine . 使用ILSpy并查找Console.WriteLine可以很容易地看到所有这些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM