2012-03-23 16 views
5

Sé que mi pregunta parece tonta, pero estoy confundido. Agradezco que alguien me aclare esto.Relación entre la clase System.Object y Structs

Sé que las estructuras, p. Int32, son tipos de valores y se crean instancias en la pila, mientras que las clases son tipos de referencia y se crean instancias en el montón. También sé que todas las estructuras se derivan del tipo System.Object, que es una clase. Me pregunto cómo es posible que el supertipo, System.Object, sea un tipo de referencia y el subtipo, Int32, ¿es un tipo de valor? ¿Dónde debo mirar para entender cómo funciona esto?

+7

Lectura relacionada: [La pila es un detalle de implementación] (http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation -detail.aspx) – Heinzi

+2

Posible duplicado de http://stackoverflow.com/questions/1682231/how-do-valuetypes-derive-from-object-referencetype-and-still-be-valuetypes – daryal

+0

Esto es conocido por el compilador –

Respuesta

11

Sé que las estructuras, p. Ej. Int32, son tipos de valores y se crean instancias en la pila, mientras que las clases son tipos de referencia y se crean instancias en el montón.

Usted no sabe que, ya que para poder ser clasificado como conocimiento una creencia debe ser verdadera . Esa creencia ciertamente no es cierta, aunque mucha gente lo cree.

Los tipos de valores son asignados a veces asignados en la pila. Las referencias a veces se asignan en la pila y se refieren a la memoria asignada en el montón. Los tipos de valores son a veces asignados en el montón. (Y, por supuesto, los tipos de valores y referencias pueden también ser asignados en registros que no son ni pila ni montón.)

lo que determina lo que se asigna almacenamiento en el montón y lo que se le asigna en la pila es los requisitos de toda la vida conocidas del almacenamiento, no qué tipo de cosa es. Si se sabe que una variable es efímera, puede asignarse en la pila; si no se sabe que es efímero, debe asignarse en el montón.

También sé que todas las estructuras se derivan del tipo System.Object, que es una clase. Me pregunto cómo es posible que el supertipo, System.Object, sea un tipo de referencia y el subtipo, Int32, ¿es un tipo de valor?

Sospecho que no entiende de qué se trata "hereda" en primer lugar si esto le resulta confuso. Cuando decimos que System.Int32, un tipo de valor, hereda de System.Object, un tipo de referencia, queremos decir que todos los miembros de Object también son miembros de Int32. Object tiene un método "ToString". Es un miembro de Object. Por lo tanto, Int32 también tiene un método "ToString", porque Int32 hereda de Object.

Eso es todos que significa herencia. Sospecho que usted cree que la herencia significa algo más, y que cualquiera que sea ese "algo" impide que los tipos de valores amplíen los tipos de referencia. Cualquier creencia que tengas que te haga pensar que los tipos de valores no pueden heredar de los tipos de referencia es claramente falsa, ya que obviamente lo hacen.

Me interesa saber qué cosas falsas creen las personas sobre los lenguajes de programación; ¿Qué es lo que piensas incorrectamente sobre la relación de herencia que impediría que los tipos de valores se derivaran de los tipos de referencia?

Debe leer y entender todos estos artículos:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

http://ericlippert.com/2011/09/19/inheritance-and-representation/

Y bono extra, éste también podría ser útil para usted :

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx

+5

No soy el OP, pero creo que una creencia común en la herencia va de esta manera: si creas un objeto de tipo 'Derived', debes (concepcionalmente) crear un objeto de tipo' Base' que luego se '' anexará '' con cada tipo derivado adicional hasta que hayas construido 'Derived' (después de todo, llamamos a todos los constructores base de la cadena). Por lo tanto, para crear un 'Int32' debe crear un' Object' y, por lo tanto, un tipo de referencia. –

+0

Gracias Eric. Estaba pensando exactamente lo que dijo Michael y fue algo extraño para mí. – Morteza

+3

@MichaelStum: la palabra clave allí es "conceptualmente" - de hecho, una construcción de un int * conceptualmente * es una construcción primero de un objeto. Pero * en la práctica * eso no es lo que * en realidad * sucede porque el sistema se ha configurado cuidadosamente para que no * no * suceda. –

2

En primer lugar, la característica distintiva de los tipos de valores no es dónde se almacenan sino cómo se pasan a los métodos. Las estructuras se pasan por valor; eso es una copia del argumento creado y pasado. Cualquier cambio en la copia dentro del método no afecta el argumento real (a menos que compartan la misma referencia) Los tipos de referencia se pasan por referencia; eso es un puntero al argumento real pasado.

Sí, las estructuras se derivan de ValueType. Y ValueType se deriva de Object. Por lo tanto, las estructuras finales también se derivan de Object. (Por ejemplo, los métodos ToString(), ==, Equals(), GetHashCode() y quizás algunos otros se definen en Object y por lo tanto también disponible en struct de)

Sin embargo, la semántica de paso de argumentos no se definen dentro de las clases a sí mismos; no hay ningún código dentro de la definición de Object que diga "cualquier instancia de mis subtipos debe pasarse por referencia" y no hay ningún código dentro de la definición de ValueType que diga "todas las instancias de mis subtipos deben pasarse por valor". [Tal vez haya un atributo especial pero eso no cuenta]. Es responsabilidad del compilador reconocerlo. (Hay algún código en algún lugar dentro de los compiladores de C# que dice "generar código tal que los descendientes de ValueType se pasarán por valor y otros se pasarán por referencia")

El blog de Eric Lippert es un recurso fantástico sobre muchos C#, y debería leer el enlace que dio @ Heinzi para obtener más aclaraciones.

Cuestiones relacionadas