Quando e perché è tenuta una classe?

In C# e C++/CLI la parola chiave sealed (o NotInheritable in VB) è utilizzato per proteggere una classe da un’eredità possibilità (la classe non è ereditabile). Io so che una funzione di programmazione object-oriented è l’ereditarietà e sento che l’uso di sealed va contro a questa funzione, si ferma in eredità.
C’è un esempio che illustra il vantaggio di sealed e quando è importante usare?

InformationsquelleAutor Aan | 2011-10-15

 

4 Replies
  1. 89
    1. Su una classe che implementa le funzionalità di sicurezza, in modo che l’oggetto originale non può essere “rappresentato”.

    2. Più in generale, di recente ho scambiato con una persona a Microsoft, che mi ha detto che hanno provato a limitare l’eredità per i luoghi dove è davvero fatto in senso pieno, perché diventa costoso prestazioni-saggio, se non trattata.
      La parola chiave sealed racconta la CLR che non c’è la classe più a cercare metodi, e che velocità le cose.

    In più di prestazioni-strumenti di valorizzazione sul mercato al giorno d’oggi, troverete una casella di controllo che provvederà a sigillare tutte le classi che non sono ereditate.

    Attenzione però, perché se si desidera consentire i plugin di assemblaggio o di scoperta attraverso il MEF, si esegue in problemi.

    • perché si esegue in problemi con il MEF se si utilizza la classe chiusa?
    • Volevo dire di stare attenti con tenuta classi riutilizzato librerie, soprattutto se si tratta di beind riutilizzati da terzi e poi reintegrati (via MEF) nel codebase. Il codebase non può ereditare una classe, ma di terze parti.
    • Il motivo #1 suoni vaghi ma, supponendo di non scrivere “funzionalità di sicurezza” la maggior parte del tempo, questo significa che motivo #1 difficilmente si applica? Motivo #2 per l’ottimizzazione delle prestazioni. Quanta differenza di prestazioni stiamo parlando? Sono abbastanza significative da giustificare la modifica di un non-sicurezza classe definizione? Anche se la risposta potrebbe essere “sì”, questo dovrebbe essere un opzione del compilatore, cioè “generare codice ottimizzato per tutti i non-classi chiuse”, piuttosto che avere noi agli sviluppatori di modificare il codice di base.
    • diventa costosa a livello di prestazioni, se non trattata questo è anche misurabile con meno di un numero pazzesco di crazy test?
    • Tenuta schifo. Si rende il test più difficile, vorrei mock un paio ASP.NET classi con FakeItEasy, ma non posso perché sono sigillati.
    • Non posso essere più d’accordo con @RayLuo. Mi ha colpito diverse volte che le persone hanno sigillato la loro classi in cui la sicurezza e le prestazioni non è davvero un problema. Il loro “sigillato” semplicemente impedito il mio ragionevole necessità di sovrascrivere le classi, ha reso le cose molto più difficili. Come Guerriero Scimpanzé, ha detto, la derisione di una classe è così comune in fase di test.

  2. 14

    Un addendum al Babbuino eccellente risposta:

    1. Se una classe non è progettato per eredità, sottoclassi, potrebbe rompere classe invarianti. Questo in realtà vale solo se si sta creando una API pubblica, naturalmente, ma come regola del pollice che di tenuta di qualsiasi classe non espressamente progettata per essere una sottoclasse.

    In una nota correlata, applicabile a sigillo con le classi: qualsiasi metodo creato virtual è un punto di estensione, o almeno sembra che dovrebbe essere un punto di estensione. Dichiarando i metodi virtual dovrebbe essere una decisione consapevole di come bene. (In C# questa è una decisione consapevole; in Java non è.)


    MODIFICA: Alcuni link importanti:

    Anche notare che Kotlin guarnizioni classi per impostazione predefinita; la sua open parola chiave è il contrario di Java finale o sigillato di C#. (Per essere sicuro, non c’è accordo universale che questa è una buona cosa.)

    • Tenuta classi cause più mal di testa che benefici. Ho continuamente trovare situazioni in cui gli sviluppatori hanno sigillato le classi, mi ha causato ore di difficoltà in quello che dovrebbe essere semplice. Interrompere tenuta classi, non sei spiritoso come pensi di essere. Guarnizione classi solo se è NECESSARIO, e anche allora, riconsiderare. Solo la mia opinione, come il ragazzo che ha a che fare con altre persone sigillato classi che non posso modificare/rimozione del sealing.
    • commento in realtà dovrebbe essere considerato come una risposta all’OP la domanda, perché essenzialmente si dà una risposta come “Quando? Difficilmente. Perché? Questo è il motivo del perché NON farlo”. Grant si dovrebbe ri-postare il tuo commento come un separato risposta e poi la raccolta di voti per farlo. 🙂
  3. 1

    Marcatura di una classe come Sealed impedisce la manomissione di importanti classi che possono compromettere la sicurezza o sulle prestazioni.

    Molte volte, tenuta di una classe ha senso anche quando uno è la progettazione di una classe di utilità che fissa per il comportamento, che non vogliamo cambiare.

    Per esempio, System spazio dei nomi in C# fornisce molte classi che sono sigillati, come String. Se non sigillata, sarebbe possibile estendere le sue funzionalità, che potrebbe essere auspicabile, in quanto è fondamentale il tipo di dato con la funzionalità.

    Allo stesso modo, structures in C# sono sempre implicitamente sigillato. Quindi non si può derivare una struttura/classe da un’altra struttura. Il ragionamento è che structures sono utilizzati al solo modello stand-alone, atomico, definito dall’utente tipi di dati, che non vogliamo modificare.

    A volte, quando si costruisce gerarchie di classe, si potrebbe desiderare di coronare un certo ramo della catena di ereditarietà, basato sul modello di dominio, o le regole di business.

    Per esempio, un Manager e PartTimeEmployee sono entrambi Employees, ma non hanno alcun ruolo dopo part-time i dipendenti dell’organizzazione. In questo caso, si potrebbe desiderare di tenuta PartTimeEmployee per prevenire l’ulteriore ramificazione. D’altra parte, se si dispone di orario o settimanale dipendenti a tempo parziale, potrebbe avere un senso per le erediterà da PartTimeEmployee.

    • Come estendere la classe String essere indesiderabili? Stringa sarebbe ancora funzionare esattamente come è attualmente, e si potrebbe avere una classe derivata con funzionalità aggiuntive quando è desiderata, quindi che problema stai parlando?
    • Inoltre, quale sarebbe il punto di “capping” la tua gerarchia di ereditarietà? Vorrebbe dire che se mai ha bisogno di estendere la gerarchia che si avrebbe per la rimozione del sealing i genitori di classe prima, che è solo inefficiente
    • Check out questo ottimo post da Eric Lippert e questo QUINDI la domanda.
    • Anche la risposta si riduce sostanzialmente a “Perché si vuole ricavare la Stringa?”, passa poi a parlare di motivi per cui si potrebbe desiderare di derivare Stringa con terminazione null, stringhe, per esempio) e dice che si dovrebbe solo lavorare intorno ad esso, senza eredità. Quindi perchè complicarsi la vita e lavorare intorno ad esso più tardi, quando si può semplicemente lasciare aperti in primo luogo e lasciare aperte tutte le opzioni
    • Per la seconda domanda, l’obiettivo dovrebbe essere quello di prevenire comportamenti indesiderati(a seconda della logica di business). È più facile unseal la classe in seguito, se necessario, piuttosto che la chiusura e la rottura di tutte le classi che dipendono da esso.
    • In particolare ciò che la logica di business potrebbe essere rotto da consentire classi derivate? E sì, è più facile per la rimozione del sealing una classe chiusa rispetto alla tenuta di un sigillo di classe, ma che non danno un vero motivo per cui si potrebbe desiderare di tenuta, in primo luogo
    • Check out questo risposta da Jon Skeet. Mi auguro che dovrebbe soddisfare le vostre domande.
    • Il mio interno scettico vede un articolo pubblicato nel 2004 ed è curioso di Eric pensieri sono evoluti nel corso degli ultimi 15 anni. EDIT: Beh, almeno MS posizione ufficiale è, per il molto link si fa riferimento.

  4. 0

    Credo che questo post ha qualche buon punto, il caso specifico è stato quando si cerca di lanciare un non-classe chiusa a qualsiasi interfaccia casuale, il compilatore non genera errore; ma quando sigillata è utilizzato il compilatore genera l’errore che non è in grado di convertire. Classe chiusa porta ulteriore codice di accesso di sicurezza.

    https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla

    • Un link a una soluzione è il benvenuto, ma assicuratevi che la vostra risposta è utile senza di essa: aggiungi contesto attorno al link modo che altri utenti hanno qualche idea di cosa è e perché è lì, quindi citare la parte più rilevante delle pagine collegate nel caso in cui la pagina di destinazione non è disponibile. le Risposte che sono poco più di un link può essere eliminato.
    • Scusa non ho intenzione di postare come risposta, ma non sembra correlata ad altre risposte e non so dove metterlo
    • Ho modificato il post, secondo il suggerimento. Originariamente vorrei contribuire con un angolo diverso (forse), ma ho ottenuto solo un downvote e noi non parlare del contenuto di sicurezza, potrebbe -1 cortesemente di sapere il motivo?

Lascia un commento