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?
Respuesta
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.
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
... 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
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). –
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.
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
Excepto que las estructuras * pueden * implementar interfaces, y un puntero de tabla de método se usa para llamarlas ... – Bevan
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
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.
Donde por "sin comprometer seriamente la funcionalidad", claramente significaban "por comprometer seriamente la funcionalidad". –
- 1. ¿Por qué una estructura no administrada no puede ser miembro de una clase administrada?
- 2. ¿por qué __getitem__ no puede ser classmethod?
- 3. ¿Por qué C++ no permite la amistad heredada?
- 4. Por qué AccessViolationException no puede ser capturado por .NET4.0
- 5. ¿Por qué DialogFragment no puede ser una clase interna?
- 6. ¿Por qué una enum de Java no puede ser definitiva?
- 7. método de C++ que puede/no puede devolver una estructura
- 8. ¿Cómo puedo crear una clase A en C#, donde A solo puede ser heredada por B, C, D?
- 9. ¿Por qué no pasar estructura por referencia una optimización común?
- 10. ¿Por qué NSWindow sin styleMask: NSTitledWindowMask no puede ser keyWindow?
- 11. En Java, ¿por qué una matriz no puede ser una variable de tipo vinculada, pero puede ser un comodín vinculado?
- 12. ¿Por qué no TextBox.Text en WPF puede ser animado?
- 13. ¿Una referencia no puede ser NULL o puede ser NULL?
- 14. C++ excepciones, ¿qué() puede ser NULO?
- 15. principal no puede ser nula
- 16. Hacer una clase no heredada
- 17. .NET base type no puede ser serializado por WCF
- 18. ¿Por qué puedo probar un genérico para nulo cuando puede no ser anulable o puede no ser un objeto?
- 19. ¿Por qué una función con modificador protegido puede ser anulada y accesible en todas partes?
- 20. ¿Por qué el lado izquierdo de una tarea no puede ser una expresión de incremento?
- 21. ¿Por qué int no puede ser nulo? ¿Cómo funciona nullable int (int?) En C#?
- 22. ¿Por qué no funciona el enlace a una estructura?
- 23. ¿Por qué .Net no tiene una estructura de datos establecida?
- 24. ¿Por qué no podemos inicializar miembros dentro de una estructura?
- 25. La mejor manera de serializar una estructura C para ser deserializada por Java, etc.
- 26. ¿Por qué una clase de nivel superior no puede ser estática en Java?
- 27. ¿Por qué la implementación explícita de una interfaz no puede ser pública?
- 28. ¿Por qué una variable de miembro Object no puede ser definitiva y volátil en Java?
- 29. Si una estructura no puede heredar otra clase o estructura, ¿por qué Int32 tiene un método ToString()?
- 30. ¿Por qué una compilación C no verifica?
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
@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. –