2011-12-25 5 views
7

Mi chiedo se esiste un modo per limitare chi può ereditare da una classe.C'è un modo per limitare chi può ereditare una classe o un'interfaccia?

  • internal: non permette di classe per essere ereditata al di fuori del gruppo di
  • sealed: classe non può essere ereditata

C'è una parola chiave o un modo per consentire solo alcune classi (diciamo che da esso è proprio spazio dei nomi) per ereditare quella classe?

Inoltre, non voglio che questa classe speciale sia generica. La mia preoccupazione non è la sicurezza ma il design in generale.

Esempio di ciò che voglio:

  • classe A.
  • classe B eredita da A
  • Classe C non può ereditare da una
+0

Rendere una classe interna non solo impedisce alle classi esterne di ereditare, ma anche di usarla.Per prevenire solo i childclass esterni sono necessari trucchi speciali, come i metodi 'internal abstract', e questo non funziona sulle interfacce. – CodesInChaos

+0

Che tipo di limite vorresti? Hai dato un'occhiata a InheritanceDemand? http://palisade.plynt.com/issues/2006Apr/link-demand/ –

+4

Nota che limitare a uno spazio dei nomi non è affatto una protezione, dal momento che un assembly canaglia potrebbe semplicemente dire 'namespace Awesome {public class Stolen: Secret { }} 'e ora possono usare' Awesome.Stolen' per accedere a 'Awesome.Secret'. –

risposta

16

C'è un modo per consentire solo a determinate classi di ereditare quella classe?

Sì. Se il codice che eredita è parzialmente attendibile allora si può porre la domanda eredità sulla classe di base e il runtime non permetterà alla classe che eredita da caricare se non soddisfa le condizioni della domanda:

https://msdn.microsoft.com/en-us/library/x4yx82e6(v=vs.100).aspx

Ovviamente, fiducia totale significa piena fiducia. Il codice completamente fidato può ereditare tutto ciò che vuole.

Ho il sospetto che tu stia cercando di imporre restrizioni che non dovresti davvero cercare di imporre. Puoi descrivere perché stai provando a fare questa cosa difficile? Probabilmente c'è un modo migliore per fare ciò che vuoi.

UPDATE:

Sto cercando di limitare l'ereditarietà dentro le mie classi nello stesso assembly.

Quindi probabilmente dovresti averlo detto in primo luogo.

Rendi tutti i costruttori della classe interna. Per ereditare da una classe, deve avere un costruttore accessibile. Se si rendono interni tutti i costruttori, solo le classi in quell'assembly possono ereditare dalla classe base.

+0

Bello. Anche se non posso usarlo perché sono su .Net 3.5 – Odys

+1

@odyodyodys: richieste di ereditarietà fornite con .NET v1. –

8

Per quanto ne so, utilizzando internal è l'unico modo per controllare chi può ereditare una classe. Se gli ereditari devono trovarsi in un assembly diverso, è possibile consentire alle classi di un altro assembly di visualizzare i componenti interni dell'assieme utilizzando l'attributo InternalsVisibleTo (l'assembly di destinazione deve essere firmato affinché funzioni con gli assembly firmati).

+1

Buona risposta, ma non è necessario firmare per InternalsVisiblePer lavorare. – Andy

+0

@Andy Grazie per il chiarimento. Ho dimenticato di menzionare che la firma è richiesta solo per gli assembly firmati. Ho deciso di menzionare la firma in primo luogo, perché ricordo il problema che ho dovuto affrontare per scoprire perché non potevo testare i metodi interni del mio assembly firmato dal mio assemblaggio di test unitario non firmato. – dasblinkenlight