2015-05-23 7 views
19

Ho una domanda circa il codice seguente:basi Console.WriteLine

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

documentazione dice:

Scrive la rappresentazione testuale di matrice specificata di oggetti, seguito dalla linea di corrente terminatore , al flusso di output standard utilizzando le informazioni di formato specificate.

Quindi la mia domanda è: Come mai WriteLine conosce la rappresentazione testuale di DateTime oggetto? Voglio dire, se creo il mio oggetto dalla mia classe, come saprebbe come convertire il valore in testo? E ancora di più, come fa a sapere qual è il valore? Come si può definire "valore" di un oggetto?

+0

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

+0

Si noti che l'ispettore dell'oggetto di Visual Studio Debugger utilizza anche un meccanismo molto simile ('MyClass.toString ') per capire cosa stampare come valore quando l'oggetto è visualizzato come una singola riga. – Superbest

+0

'Console.WriteLine()' chiama implicitamente 'ToString()', quindi per il tuo oggetto devi implementare/sovrascrivere il metodo 'ToString()'. – Jaider

risposta

17

Come mai WriteLine conosce la rappresentazione di testo dell'oggetto DateTime? Voglio dire, se creo il mio oggetto dalla mia classe, come saprebbe come convertire il valore in testo?

Console.WriteLine ha un set of overloads corrispondenza a tipi specifici (principalmente primitive). Se il compilatore non corrisponde a un sovraccarico con il tipo fornito, corrisponde a sovraccarico System.Object (concesso fornire un singolo parametro). Se ciò accade, controlla se il tipo implementa IFormattable, se lo fa, invoca IFormattable.ToString(null, Formatter). In caso contrario, invoca ToString sul tuo oggetto. ToString è definito in System.Object, da cui tutti gli oggetti ereditano.Ogni oggetto che desidera una rappresentazione personalizzata sovrascrive il comportamento predefinito, come fa DateTime.

Per esempio, supponiamo di avere una classe Foo con una proprietà Bar di stringa, e si desidera Console.WriteLine per stampare qualcosa di significativo quando passa il tuo Foo ad esso:

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

E ora vogliamo passarlo Console.WriteLine :

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

Produrrebbe "bar".

9

Poiché non v'è sovraccarico per Console.WriteLine(DateTime), come nel suo caso, il sovraccarico Console.WriteLine(Object) viene chiamato e this overload calls la TextWriter.WriteLine(object) overload che è implemented as:

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

Come si può vedere, questo metodo controlla se questo tipo di oggetto attrezzi IFormattable interface oppure no. Dal Datetime implements this interface, verrà chiamato il tuo f.ToString(null, FormatProvider). Dal documentation il primo parametro di questo metodo è:

Un riferimento null (Nothing in Visual Basic) per utilizzare il formato di default definito per il tipo di realizzazione IFormattable.

E dalla documentazione metodo del DateTime.ToString(String, IFormatProvider):.

Se il formato è null o una stringa vuota (""), il formato standard specificatore, "G", viene utilizzato.

Ciò significa, la rappresentazione sarà una combinazione delle proprietà ShortDatePattern e LongTimePattern appartenenti al CurrentCulture

Se si desidera un formato speciale per la vostra classe personalizzata, è possibile override the .ToString() method del vostro tipo di cambiare il suo comportamento .

7

Contrariamente a quanto alcune persone pensano, DateTime.ToString()non sarà chiamato. In .NET, un oggetto può avere due modi per "stringere" se stesso: ignorando il metodo string Object.ToString() e implementando l'interfaccia IFormattable. DateTime fa entrambi.

Ora ... quando si tenta di fare

Console.WriteLine(DateTime.Now); 

il vuoto viene selezionato public static void WriteLine(Object value) sovraccarico (si può vedere se Ctrl + clic su WriteLine in Visual Studio). Questo metodo chiama semplicemente il metodo TextWriter.WriteLine(value), che fa:

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

Tutto questo può essere facilmente visibile utilizzando ILSpy e cercando il Console.WriteLine.