2015-05-23 2 views
19

У меня есть вопрос о следующем коде:Console.WriteLine основы

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

Документация говорит:

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

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

+0

См. Https://msdn.microsoft.com/en-gb/library/ms173154%28v=vs.80%29.aspx – adaam

+0

Обратите внимание, что инспектор объектов Visual Studio Debugger также использует очень похожий механизм ('MyClass.toString '), чтобы выяснить, что печатать как значение, когда объект отображается как одна строка. – Superbest

+0

'Console.WriteLine()' неявно вызывает 'ToString()', поэтому для вашего собственного объекта вам необходимо реализовать/переопределить метод ToString(). – Jaider

ответ

17

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

Console.WriteLine имеет set of overloads, соответствующий определенным типам (в основном примитивным). Если компилятор не соответствует перегрузке с предоставленным типом, он соответствует перегрузке System.Object (предоставлен вам один параметр). Если это произойдет, он проверяет, реализует ли тип IFormattable, если он это делает, он вызывает IFormattable.ToString(null, Formatter). Если это не так, он вызывает 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); 
} 

Получил бы «бар».

9

Поскольку нет перегрузки Console.WriteLine(DateTime), как в вашем случае, перегрузка Console.WriteLine(Object) называется и this overload callsTextWriter.WriteLine(object) overload который implemented as:

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

Как вы можете видеть, этот метод проверяет, если реализует этот тип объекта IFormattable interface или нет. Начиная с Datetime implements this interface, будет вызываться ваш f.ToString(null, FormatProvider). Из documentation первого параметра этого метода заключается в следующем:

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

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

Если формат является нулевым или пустая строка (""), стандартный формат спецификатор "G" используется.

Это означает, что представление будет сочетанием свойств ShortDatePattern и LongTimePattern принадлежащих к вашим CurrentCulture

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

7

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

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

Console.WriteLine(DateTime.Now); 

пустота выбрана public static void WriteLine(Object value) перегрузки (вы можете увидеть, если вы Ctrl + Click на 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.

Смежные вопросы