Основы Console.Writeline

У меня вопрос по следующему коду:

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

В документации говорится:

Записывает текстовое представление указанного массива объектов, за которым следует признак конца текущей строки, в стандартный поток вывода, используя указанную информацию о формате.

Итак, мой вопрос: почему WriteLine знает текстовое представление объекта DateTime? Я имею в виду, если я создам свой собственный объект из своего собственного класса, как он узнает, как преобразовать значение в текст? И даже более того, как он узнает, какова ценность? Как определить «ценность» объекта?


person CuriousGuy    schedule 23.05.2015    source источник
comment
См. msdn.microsoft.com/en-gb /library/ms173154%28v=vs.80%29.aspx   -  person adaam    schedule 23.05.2015
comment
Обратите внимание, что инспектор объектов отладчика Visual Studio также использует очень похожий механизм (MyClass.toString) для определения того, что печатать в качестве значения, когда объект отображается как одна строка.   -  person Superbest    schedule 24.05.2015
comment
Console.WriteLine() неявно вызывает ToString(), поэтому для вашего собственного объекта вы должны реализовать / переопределить метод ToString().   -  person Jaider    schedule 25.10.2016


Ответы (3)


Почему WriteLine знает текстовое представление объекта DateTime? Я имею в виду, если я создам свой собственный объект из своего собственного класса, как он узнает, как преобразовать значение в текст?

Console.WriteLine имеет набор перегрузок соответствие определенным типам (в основном примитивам). Если компилятор не соответствует перегрузке с предоставленным типом, он совпадает с перегрузкой, принимающей System.Object (при условии, что вы указываете один параметр). Если это произойдет, он проверяет, реализует ли тип IFormattable, если это так, он вызывает _ 4_. В противном случае он вызывает ToString для вашего объекта. ToString определен в System.Object, от которого наследуются все объекты. Каждый объект, которому требуется настраиваемое представление, отменяет поведение по умолчанию, как это делает DateTime.

Например, допустим, у вас есть класс Foo со строковым свойством Bar, и вы хотите, чтобы 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);
}

Дала бы «планку».

person Yuval Itzchakov    schedule 23.05.2015

Поскольку для Console.WriteLine(DateTime) нет перегрузки, как в вашем случае, вызывается перегрузка Console.WriteLine(Object) и эта перегрузка вызывает TextWriter.WriteLine(object) перегрузку < / a>, который реализован как:

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

Как видите, этот метод проверяет, реализует ли этот тип объекта IFormattable интерфейс или нет. Поскольку Datetime реализует этот интерфейс, будет вызываться ваш f.ToString(null, FormatProvider). Из документации этого метода первый параметр:

Пустая ссылка (Nothing в Visual Basic) для использования формата по умолчанию, определенного для типа реализации IFormattable.

И из документации метода DateTime.ToString(String, IFormatProvider):

Если формат равен нулю или пустой строке (""), описатель стандартного формата _ 9_., Используется.

Это означает, что представление будет представлять собой комбинацию _ 10_ и _ 11_ свойств, принадлежащих вашему _ 12_

Если вам нужен специальный формат для вашего настраиваемого класса, вы можете переопределить .ToString() метод вашего типа, чтобы изменить его поведение.

person Soner Gönül    schedule 23.05.2015

Вопреки тому, что думают некоторые люди, DateTime.ToString() не будет вызван. В .NET объект может иметь два способа "строкового преобразования" самого себя: переопределение метода string Object.ToString() и реализация _3 _ интерфейс. DateTime делает и то, и другое.

Теперь ... Когда вы пытаетесь сделать

Console.WriteLine(DateTime.Now);

выбрана перегрузка void public static void WriteLine(Object value) (вы можете увидеть ее, нажав Ctrl + щелчок на WriteLine в Visual Studio). Этот метод просто вызывает метод TextWriter.WriteLine(value), который:

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

Все это можно легко увидеть, используя ILSpy и ища Console.WriteLine.

person xanatos    schedule 23.05.2015