2010-02-22 28 views
73

Estoy leyendo CLR a través de C# por Jeffery Richter y dice que una estructura es un tipo de valor y no se puede heredar. Por qué no? ¿Alguna razón técnica? ¿O filosóficos?¿Por qué una estructura C# no puede ser heredada?

+1

Tal vez más una pregunta que una respuesta, pero todas las estructuras heredan System.ValueType y si miras con reflector, System.ValueType es una clase abstracta :) Todas las estructuras se heredan. Creo que sería beneficioso si las respuestas a esta pregunta aclararan esto. – Marek

+3

@Marek: Lea el segundo párrafo de mi respuesta aquí para obtener una aclaración al respecto: http://stackoverflow.com/questions/1978589/why-do-structs-need-to-be-boxed/1978597#1978597 En resumen, heredar de 'ValueType' no tiene una implicación estructural para la instancia struct. De hecho, un valor struct no es realmente un 'System.ValueType' en lo que respecta al tiempo de ejecución (es decir, en IL, no se puede pasar un' int' a un método que toma un 'ValueType' sin usar explícitamente el' cuadro 'instrucción). Solo una estructura en caja (que es un tipo de referencia) realmente lo es. –

Respuesta

77

Editar: Aparentemente hay serias preocupaciones editoriales sobre esta publicación. Ver la sección de comentarios.

Un poco de ambos.

Filosóficamente, funciona - no hay clases, que son la piedra angular "real" para la programación orientada a objetos, y hay estructuras, que son tipos de datos ligeros para el almacenamiento, pero permiten a objetos como método exige familiaridad y conveniencia.

Técnicamente,, al ser un "tipo de valor" significa que toda la estructura, es decir, todos sus contenidos, se almacenan (generalmente) donde quiera que tenga una variable o miembro de ese tipo. Como variable local o parámetro de función, eso significa en la pila. Para las variables miembro, eso significa almacenado por completo como parte del objeto.

Como ejemplo (principal) de por qué la herencia es un problema, considere cómo el almacenamiento se ve afectado a un nivel bajo si permite que las estructuras tengan subtipos con más miembros. Cualquier cosa que guarde ese tipo de estructura ocuparía una cantidad variable de memoria basada en qué subtipo terminó conteniendo, lo que sería una pesadilla de asignación. Un objeto de una clase dada ya no tendría un tamaño constante conocido en el momento de la compilación, y lo mismo sería cierto para los cuadros de pila de cualquier llamada a un método. Esto no ocurre con los objetos, que tienen almacenamiento asignado en el montón y en su lugar tienen referencias de tamaño constante a ese almacenamiento en la pila o dentro de otros objetos.

Esto es solo una explicación intuitiva de alto nivel. Consulte los comentarios y otras respuestas para obtener información más detallada y más detallada.

+0

Gracias, Jesse. Tu explicación me dio algunas chispas. En cuanto a mi comprensión, OOP tiene un costo. Si solo hay "ref-type" y todo sucede en el montón, cuya gestión es mucho menos eficiente que la pila, el rendimiento será pobre. Entonces viene el llamado "valor-tipo" que vive en la pila para un mejor rendimiento, y es por el lugar de la asignación y el paradigma de uso de memoria que sella el valor de tipo. – smwikipedia

+0

... y si podemos descifrar un nuevo paradigma de uso de la memoria además de stack y heap, tal vez surjan nuevos tipos de datos. – smwikipedia

+0

En cuanto a los nuevos paradigmas del uso de la memoria ... Es dudoso. :) Cualquier otro paradigma de uso de la memoria probablemente se superpondrá a la pila o a la asignación del montón, o ambas cosas. (Por ejemplo, cierres en lenguajes funcionales, que podrían valer la pena comprender). –

32

Porque es la forma en que se representan las estructuras en .NET. Son tipos de valores y tipos de valores que no tienen un puntero de tabla de método que permita la herencia.

+17

Se podría agregar: Y la razón por la que no tienen un puntero de tabla de métodos es porque los tipos de valores están diseñados para ser lo más livianos posible. – bitbonk

+9

Excepto que las estructuras * pueden * implementar interfaces, y un puntero de tabla de método se usa para llamarlas ... – Bevan

+1

Hay varias maneras en que las estructuras podrían ser útiles para la herencia sin necesitar información de tipo por instancia: (1) diciendo que el * solo * efecto de 'FooStruct: BarStruct' sería que un tipo genérico restringido a' BarStruct' podría acceder a los miembros (* incluyendo los campos *) de ese tipo directamente; (2) diciendo que cualquier tipo 'FooStruct: BarStruct' debe estar contractualmente obligado a usar sus campos heredados de tal manera que un' BarStruct' formado al copiar los campos heredados de un 'FooStruct' existente debe ser un' BarStruct' válido y ... – supercat

14

Puede encontrar las respuestas a la pregunta Why are .NET value types sealed? relevante. En ella, se refiere a @logicnpECMA 335, que establece:

8.9.10 Tipo de valor herencia

  • [...]
  • serán sellados para evitar hacer frente a las complicaciones del valor de corte.
  • Las reglas más restrictivas especificadas aquí permiten una implementación más eficiente sin comprometer seriamente la funcionalidad.
+1

Donde por "sin comprometer seriamente la funcionalidad", claramente significaban "por comprometer seriamente la funcionalidad". –

Cuestiones relacionadas