2012-05-23 12 views
19
int a = 2; 

Console.WriteLine(a.ToString()); // displays 2 

// definition of ToString() here - public override string ToString(); 

Ora, qui sono alcuni dei miei comprensioni:Se una struct non può ereditare un'altra classe o struct, perché Int32 ha un metodo ToString()?

  1. Tutte le classi in .NET ottenere un metodo ToString(), che viene ereditato dalla classe Object.
  2. Una struttura non può essere derivata da una classe o un'altra struttura. int è una struttura di tipo Int32, che ottiene un paio di metodi ToString() [Con parametri] dalle interfacce implementate.
  3. V'è anche un ToString() [senza params] funzione struct Int32

Secondo http://msdn.microsoft.com/en-us/library/system.int32.tostring.aspx,

struct Int32 sovrascrive ValueType.ToString metodo

Se una struct() non posso ereditare qualche classe o struttura, puoi spiegare come questo metodo ToString() è disponibile per Int32?

+0

tutti i tipi derivano da Object in qualche modo. int deriva da ValueType che deriva da Object. La tua ipotesi 2 è sbagliata. http://ptgmedia.pearsoncmg.com/images/chap13_0321169514/elementLinks/13fig02.gif – 0lukasz0

+0

@ 0lukasz0 [Non * tutto * deriva da oggetto] (http://blogs.msdn.com/b/ericlippert/archive/2009/ 06/08/non-tutto-deriva-da-object.aspx). – vcsjones

+0

"struct Int32 sovrascrive il metodo ValueType.ToString()" risponde alla tua stessa domanda. –

risposta

30

Se una struct non può ereditare una classe o struct,

questo non è vero. Tutte le strutture (e i tipi di valore predefiniti, come System.Int32, System.Single, ecc.) Ereditano sempre implicitamente da System.ValueType (che, a sua volta, eredita da System.Object).

Tuttavia, non è possibile creare una struttura che erediti da altro.

Questo è chiaramente espresso nel linguaggio C# spec, 4.1.1:

4.1.1 Il tipo System.ValueType

Tutti i tipi di valore implicitamente ereditano dalla System.ValueType classe, che , a sua volta, eredita dall'oggetto di classe. Non è possibile per nessun tipo derivare da un tipo di valore, e i tipi di valore sono quindi implicitamente sigillati (§10.1.1.2).

Poi, dopo (4.1.3) struct è esplicitamente definito come un tipo di valore:

4.1.3 tipi Struct

Un tipo struct è un tipo di valore che può dichiarare costanti , campi, metodi, proprietà, indicizzatori, operatori, costruttori di istanze, costruttori statici e tipi nidificati.

+0

Quindi, se sto creando una nuova struttura personalizzata, non posso ereditarla da nessun'altra classe, ma le strutture esistenti sono ereditate da ValueType? Puoi confermare? – robot

+5

@robot * Tutte le strutture * eredita da 'ValueType', anche quelli che si crea, anche se non si esplicita che la stessa eredita da ValueType (che non si poteva fare, anche se si voleva). – vcsjones

+0

Grazie per la risposta – robot

1

Int32 implementa IFormattable, che definisce il metodo ToString

+2

IFormattable definisce un metodo ToString parametrizzato, non il metodo ToString senza parametri su cui l'OP sta chiedendo informazioni. – phoog

1

Ogni definizione di un tipo derivato da ValueType definisce realtà due tipi distinti di cose nel runtime: un tipo di oggetto mucchio (che deriva da ValueType e passare da Object e che contiene informazioni sul tipo incorporato) e un tipo di percorso di archiviazione (che non contiene alcuna informazione di tipo incorporato, ma richiede invece che il codice che lo utilizza debba avere altri mezzi per sapere di cosa si tratta). Un'istanza del tipo di oggetto heap contiene un campo del tipo di posizione di archiviazione e il codice che tenta di accedere a this accede a tale campo. Se un tipo di valore viene inoltrato implicitamente o esplicitamente a un percorso di archiviazione di tipo di riferimento, il sistema creerà un nuovo oggetto heap con il tipo appropriato e copierà tutti i campi pubblici e privati ​​del tipo valore nei campi corrispondenti all'interno dell'oggetto heap. Se un oggetto heap viene eseguito il cast in un percorso di memorizzazione di tipo valore, tutti i campi pubblici e privati ​​dall'oggetto heap verranno copiati nel percorso di memorizzazione del tipo valore.

Se si tenta di utilizzare qualsiasi Object o metodo di interfaccia su un oggetto heap di un tipo valore, il metodo verrà chiamato proprio come qualsiasi altro metodo heap-object. Se il tentativo viene effettuata su un magazzino value-type, per qualsiasi metodo diverso GetType, il compilatore genera uno speciale codice operativo "vincolato" che informa il runtime del tipo della posizione di memoria e istruisce il runtime per chiamare l'indirizzo il metodo appropriato per quel tipo. Poiché il compilatore avrà a disposizione il tipo di percorso di archiviazione e il runtime può utilizzarlo per trovare il metodo appropriato, il metodo appropriato può essere richiamato direttamente nel percorso di archiviazione, senza dover prima creare un nuovo oggetto heap. GetType è l'unica eccezione notevole; poiché funziona esaminando le informazioni di tipo incorporate in un oggetto, può funzionare solo su elementi che contengono informazioni di tipo incorporato. Di conseguenza, il suo argomento verrà convertito nel modulo oggetto-heap prima della chiamata; GetType sarà quindi in grado di esaminare le informazioni sul tipo incorporato di tale oggetto heap.

+0

Stavi tentando di evitare di usare il termine * boxing * (o una sua variante)? –

+0

@BenVoigt: Non mi aspetto che invocando 'ToString' su un' Int32' comporterebbe boxe [che potrebbe essere definito in modo tale da richiedere la boxe, ma non riesco a pensare perché sarebbe].Potrebbe essere stato utile menzionare che il processo di conversione di un oggetto nella sua forma heap-oggetto è chiamato boxing, ma non ero sicuro di come e dove meglio dirlo senza distrarre dal punto principale, che è tale processo non è necessario quando si chiama 'Int32.ToString()'. – supercat

Problemi correlati