Sto leggendo CLR tramite C# di Jeffery Richter e si dice che una struttura è un tipo di valore e non può essere ereditata. Perchè no? Qualche ragione tecnica? O filosofici?Perché una struttura C# non può essere ereditata?
risposta
Modifica: Ci sono serie preoccupazioni editoriali su questo post, a quanto pare. Vedi la sezione commenti.
Un po 'di entrambi.
Filosoficamente, funziona - ci sono classi, che sono il "vero" building block per programmazione orientata agli oggetti, e ci sono le strutture, che sono tipi di dati leggeri per lo stoccaggio, consentono oggetto simile metodo chiede familiarità e convenienza.
Tecnicamente, essendo un "tipo di valore" significa che l'intera struttura, tutto il suo contenuto, viene (solitamente) memorizzata ovunque sia presente una variabile o un membro di quel tipo. Come parametro locale o parametro di funzione, significa in pila. Per le variabili membro, ciò significa memorizzato interamente come parte dell'oggetto.
Come esempio (primario) del motivo per cui l'ereditarietà è un problema, considerare se lo storage è interessato a un livello basso se si consente alle strutture di avere sottotipi con più membri. Qualsiasi cosa memorizzasse quel tipo di struttura occuperebbe una quantità variabile di memoria in base a quale sottotipo finiva con il contenere, il che sarebbe un incubo di allocazione. Un oggetto di una data classe non avrebbe più una dimensione costante e conosciuta al momento della compilazione e lo stesso sarebbe vero per i frame stack di qualsiasi chiamata di metodo. Ciò non si verifica per gli oggetti che dispongono di memoria allocata nell'heap e hanno invece riferimenti a dimensioni costanti a quella memoria nello stack o all'interno di altri oggetti.
Questa è solo una spiegazione intuitiva e di alto livello - Vedi commenti e altre risposte per informazioni più dettagliate e più dettagliate.
Grazie, Jesse. La tua spiegazione mi ha dato delle scintille. Per quanto ne so, l'OOP ha un costo. Se c'è solo "ref-type" e tutto accade nell'heap, la cui gestione è molto meno efficiente dello stack, le prestazioni saranno scarse. Quindi arriva il cosiddetto "valore-tipo" che vive nello stack per prestazioni migliori, ed è a causa del luogo dell'allocazione e del paradigma dell'utilizzo della memoria che rende il valore-type sigillato. – smwikipedia
... e se riusciamo a capire un paradigma nuovo di zecca dell'uso della memoria oltre allo stack e all'heap, potrebbero sorgere nuovi tipi di dati. – smwikipedia
Per quanto riguarda i nuovi paradigmi dell'uso della memoria ... È dubbio. :) Qualsiasi altro paradigma di utilizzo della memoria è probabile che sia sovrapposto a stack o heap allocazione o entrambi. (Ad esempio chiusure in linguaggi funzionali, che potrebbero valere il tuo tempo per capire.) –
Perché è il modo in cui le strutture sono rappresentate in .NET. Sono tipi di valore e i tipi di valore non hanno un puntatore della tabella del metodo che consente l'ereditarietà.
Si potrebbe aggiungere: E il motivo per cui non hanno un puntatore della tabella dei metodi è perché i tipi di valore sono progettati per essere il più leggeri possibile. – bitbonk
Tranne che le strutture * possono * implementare interfacce e un puntatore della tabella del metodo viene usato per chiamarle ... – Bevan
Esistono diversi modi in cui le strutture possono supportare l'ereditarietà senza bisogno di informazioni sul tipo di istanza: (1) dicendo che l'effetto * solo * di «FooStruct: BarStruct» sarebbe che un tipo generico vincolato a «BarStruct» sarebbe in grado di accedere direttamente ai membri (* compresi i campi *) di quel tipo; (2) dicendo che qualsiasi tipo 'FooStruct: BarStruct' deve essere contrattualmente vincolato ad usare i suoi campi ereditati in modo tale che un' BarStruct' formato copiando i campi ereditati di un 'FooStruct esistente 'deve essere un' BarStruct' valido e ... – supercat
È possibile trovare le risposte a SO Domanda Why are .NET value types sealed? rilevanti. In esso, si riferisce a @logicnpECMA 335, in cui si afferma:
8.9.10 Tipo di valore eredità
- [...]
- sarà sigillato per evitare di affrontare le complicazioni di valore affettare.
- Le regole più restrittive qui specificate consentono un'implementazione più efficiente senza compromettere seriamente la funzionalità.
Dove per "senza compromettere seriamente la funzionalità", intendevano chiaramente "compromettendo severamente la funzionalità". –
- 1. Perché una Struct non può essere derivata da un'altra struttura?
- 2. Perché una struttura non gestita non può essere un membro di una classe gestita?
- 3. perché una variabile locale non può essere volatile in C#?
- 4. Rendere una classe non ereditata
- 5. Perché datetime non può essere confrontato?
- 6. Struttura directory EXTJS: cosa può essere cancellato?
- 7. C# smtp.google.com non può essere risolto
- 8. Perché una classe Java non può essere dichiarata come statica?
- 9. Perché una grammatica LL non può essere lasciata ricorsiva?
- 10. Perché una stringa non può essere nulla in Go?
- 11. Perché DialogFragment non può essere una classe interna?
- 12. perché jspService() non può essere sovrascritto?
- 13. Swift: Enum 'non può essere costruito perché non ha inizializzatori accessibili' non può essere costruita
- 14. Perché una struttura può memorizzare le proprie dimensioni?
- 15. Xcode 7.1: il simulatore non può essere aperto perché l'identità dello sviluppatore non può essere confermata
- 16. sindacati in C#: Struttura membri non sembrano essere stati allineati
- 17. Perché AccessViolationException non può essere catturato da .NET4.0
- 18. Perché AnyVal non può essere utilizzato in un controllo isInstanceOf?
- 19. Perché file_get_contents() restituiscono l'errore "Nome file non può essere vuoto"?
- 20. Spring - applicationContext.xml non può essere aperto perché non esiste
- 21. Non può essere sigillato perché non è un override
- 22. L'amicizia è ereditata in C++?
- 23. L'elemento array non può essere ponticellato all'obiettivo-C
- 24. @JavascriptInterface non può essere risolto
- 25. "ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass" non può essere incorporato
- 26. Perché ErrorString una struttura, non è una stringa
- 27. ReflectionException non può essere catturato?
- 28. Perché simulare HttpContext se può essere costruito?
- 29. Struttura/tipo personalizzato che può essere utilizzato con lo switch()
- 30. Perché una funzione con modificatore protetto può essere ignorata e accessibile ovunque?
Forse più una questione di una risposta, ma tutte le strutture ereditano System.ValueType e se si guarda con riflettore, System.ValueType è una classe astratta :) Tutte le strutture ereditano esso. Penso che sarebbe utile se le risposte a questa domanda chiarissero questo. – Marek
@Marek: Leggi il secondo paragrafo della mia risposta qui per chiarimenti su questo: http://stackoverflow.com/questions/1978589/why-do-struct-need-to-be-boxed/1978597#1978597 Per riassumere, ereditare da 'ValueType' non ha implicazioni strutturali per l'istanza di struct. Infatti, un valore struct non è realmente un 'System.ValueType' per quanto riguarda il runtime (cioè in IL, non puoi passare un' int' a un metodo che prende un 'ValueType' senza usare esplicitamente la casella' 'istruzione). Lo è solo una struttura in scatola (che è un tipo di riferimento). –