How does Console.Writeline know how to print an object as text/string?
Asked Answered
T

3

18

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? 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?

Tiffany answered 23/5, 2015 at 14:11 Comment(8)
See msdn.microsoft.com/en-gb/library/ms173154%28v=vs.80%29.aspxHoedown
Note that Visual Studio Debugger's object inspector also uses a very similar mechanism (MyClass.toString) to figure out what to print as the value when the object is displayed as a single row.Huzzah
Console.WriteLine() implicitly calls ToString(), so for your own object you have to implement/override ToString() method.Chicoine
Does this answer your question? How does Console.WriteLine() know how to convert an object to a stringScript
@KarlKnechtel - this one has the better answer though.Eakin
@Eakin I agree, but this title is awful, and the only obvious way to fix it would be to copy the other title, which the system doesn't allow.Script
@KarlKnechtel thank you for the feedback, you are right. I updated the title to be more clear and searchable.Tiffany
Good enough for me - voted to dupe-close the other one.Script
B
18

How come WriteLine knows the text representation of DateTime object? 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). 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). If that happens, it checks to see if the type implements IFormattable, if it does, it invokes IFormattable.ToString(null, Formatter). If it doesn't, it invokes ToString on your object. ToString is defined in System.Object , which all objects inherit from. Every object that wants a custom representation overrides the default behavior, like DateTime does.

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:

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

And now we want to pass it Console.WriteLine:

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

Would yield "bar".

Burke answered 23/5, 2015 at 14:14 Comment(0)
V
9

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:

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. Since Datetime implements this interface, your f.ToString(null, FormatProvider) will be called. 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.

And from the DateTime.ToString(String, IFormatProvider) method's documentation:

If format is null or an empty string (""), the standard format specifier, "G"., is used.

That means, the representation will be a combination of the ShortDatePattern and LongTimePattern properties belonging to your CurrentCulture

If you want a special format for your custom class, you can override the .ToString() method of your type to change its behaviour.

Vandal answered 23/5, 2015 at 14:13 Comment(0)
F
7

Contrary to what some persons think, DateTime.ToString() won't be called. In .NET, an object can have two ways to "stringize" itself: overriding the string Object.ToString() method and implementing the IFormattable interface. DateTime does both.

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). This method simply calls the TextWriter.WriteLine(value) method, that does:

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.

Facia answered 23/5, 2015 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.