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

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

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

Ahora, aquí están algunos de mis entendimientos:Si una estructura no puede heredar otra clase o estructura, ¿por qué Int32 tiene un método ToString()?

  1. Todas las clases en .net consiguen un método ToString(), que se hereda de la clase Object.
  2. Una estructura no se puede derivar de una clase u otra estructura. int es una estructura de tipo Int32, que obtiene un par de ToString() [con parámetros] de las interfaces que implementa.
  3. También hay un ToString() [sin params] función en struct Int32

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

struct Int32 anula ValueType.ToString método()

Si un struct no puede heredar alguna clase o estructura, ¿puede explicar cómo está disponible este método ToString() para Int32?

+0

todos los tipos derivan de Object de alguna manera. int deriva de ValueType que deriva de Object. Tu suposición 2 es incorrecta. http://ptgmedia.pearsoncmg.com/images/chap13_0321169514/elementLinks/13fig02.gif – 0lukasz0

+0

@ 0lukasz0 [No * todo * se deriva del objeto] (http://blogs.msdn.com/b/ericlippert/archive/2009/ 08/06/not-everything-derives-from-object.aspx). – vcsjones

+0

"struct Int32 reemplaza el método ValueType.ToString()" responde a su propia pregunta. –

Respuesta

30

Si una estructura no puede heredar alguna clase o estructura,

esto no es cierto. Todas las estructuras (y los tipos de valores incorporados, como System.Int32, System.Single, etc.) siempre heredan implícitamente de System.ValueType (que, a su vez, hereda de System.Object).

Sin embargo, no se puede hacer una estructura que herede de cualquier cosa.

Esto es claramente indicado en las especificaciones de lenguaje C#, 4.1.1:

4.1.1 El tipo System.ValueType

Todos los tipos de valor heredan implícitamente de la System.ValueType clase, que , a su vez, hereda de un objeto de clase. No es posible derivar ningún tipo de un tipo de valor y, por lo tanto, los tipos de valor están sellados implícitamente (§10.1.1.2).

Luego, más tarde (4.1.3) struct se define explícitamente a ser un tipo de valor:

4.1.3 tipos Struct

Un tipo struct es un tipo de valor que pueden declarar constantes , campos, métodos, propiedades, indizadores, operadores, constructores de instancias, constructores estáticos y tipos anidados.

+0

Entonces, si estoy creando una nueva estructura personalizada, ¿no puedo heredar de ninguna otra clase, pero las estructuras existentes se heredan de ValueType? ¿Puedes confirmar? – robot

+5

@robot * Todas las * estructuras heredan de 'ValueType', incluso las que usted crea, incluso si no declara explícitamente que hereda de ValueType (que no podría hacer aunque quisiera). – vcsjones

+0

Gracias por su respuesta – robot

1

Int32 implementa IFormattable, que define el método ToString

+2

IFormattable define un método ToString parametrizado, no el método ToString sin parámetros sobre el que el OP está preguntando. – phoog

1

Cada definición de un tipo derivado de ValueType define realmente dos tipos distintos de cosas en el tiempo de ejecución: un tipo de objeto montón (que deriva de ValueType y en pasar de Object, y que contiene información de tipo incrustado), y un tipo de ubicación de almacenamiento (que no contiene información de tipo incrustado, sino que requiere que el código que lo utiliza debe tener algún otro medio para saber de qué se trata). Una instancia del tipo de objeto de montón contiene un campo del tipo de ubicación de almacenamiento, y el código que intenta acceder al this accederá a ese campo. Si un tipo de valor se convierte implícita o explícitamente en una ubicación de almacenamiento de tipo de referencia, el sistema creará un nuevo objeto de montón con el tipo apropiado y copiará todos los campos públicos y privados del tipo de valor en los campos correspondientes dentro del objeto de montón. Si un objeto de montón se convierte en una ubicación de almacenamiento de tipo de valor, todos los campos públicos y privados del objeto de montón se copiarán en la ubicación de almacenamiento de tipo de valor.

Si se intenta utilizar cualquier Object o método de interfaz en un objeto de montón de un tipo de valor, el método se llamará igual que cualquier otro método de objeto de montón. Si el intento se realiza en una ubicación de almacenamiento de tipo valor, para cualquier método que no sea GetType, el compilador generará un código de operación "restringido" especial que informará el tiempo de ejecución del tipo de ubicación de almacenamiento e indicará a Runtime que llame a la dirección de el método apropiado para ese tipo. Como el compilador tendrá el tipo de ubicación de almacenamiento disponible, y el tiempo de ejecución puede usarlo para encontrar el método apropiado, el método apropiado puede invocarse directamente en la ubicación de almacenamiento, sin tener que crear primero un nuevo objeto de montón. GetType es la única excepción notable; dado que funciona al examinar la información de tipo incrustada en un objeto, solo puede funcionar en elementos que tienen información de tipo incrustada. En consecuencia, su argumento se convertirá a la forma de objeto de montón antes de la llamada; GetType podrá examinar la información de tipo incrustado de ese objeto de montón.

+0

¿Estabas tratando de evitar usar el término * boxing * (o cualquier variación del mismo)? –

+0

@BenVoigt: No esperaría que invocar 'ToString' en un' Int32' involucraría el boxeo [podría definirse de tal manera que requiera el boxeo, pero no puedo pensar por qué sería].Hubiera sido bueno mencionar que el proceso de convertir un objeto a su forma de objeto de montón se llama boxeo, pero no estaba seguro de cómo y dónde decirlo mejor sin distraerme del punto principal, que es que tal proceso no es necesario cuando se llama a 'Int32.ToString()'. – supercat

Cuestiones relacionadas