11
votes

Existe-t-il un moyen de limiter qui peut hériter d'une classe ou d'une interface?

Je me demande s'il y a un moyen de limiter qui peut hériter d'une classe.

  • interne : ne permet pas à la classe d'être héritée en dehors de l'assemblage
  • scellé : la classe ne peut pas être héritée

    Y a-t-il un mot clé ou un moyen de permettre uniquement certaines classes (disons de son propre espace de noms uniquement) d'hériter de cette classe?

    En outre, je ne veux pas que cette classe spéciale soit générique. Mon inquiétude n'est pas la sécurité mais la conception en général.

    Exemple de ce que je veux:

    • Classe A.
    • la classe B hérite d'un
    • la classe C ne peut pas hériter d'un

8 commentaires

Faire une classe interne n'empêche non seulement que des classes extérieures à héritage, mais aussi de l'utiliser. Pour empêcher juste des classes d'enfants externes, vous avez besoin de trucs spéciaux, tels que les méthodes abstrait internes


Quel genre de limite voudriez-vous? Avez-vous eu un coup d'oeil à l'inhéritangeemand? Palisade.plynt.com/issues/2006apr/link-Demand


Notez que la limitation de la limitation d'un espace de noms n'est pas beaucoup une protection du tout, puisqu'un assemblée de voyous pourrait simplement dire Espace de noms impressionnant {Classe publique volée: Secret {}} Et maintenant, ils peuvent utiliser awesome.stolen pour accéder à awesome.secret .


- WOW - Raymond Chen! J'ai lu sur vous! J'aime ton blog :) Mon inquiétude n'est pas la sécurité. J'essaie de limiter l'héritage au sein de mes classes dans la même assemblée.


@ODYODYODYS: Vous devriez probablement avoir dit que dans la première place . Cela est facile à faire. Faire tous les constructeurs internes. Ensuite, seules les classes dans le même assembly peuvent hériter, car l'héritage nécessite une CTOR accessible.


@ Calcullippert désolé à ce sujet, je n'étais pas clair. Édité et ajouté un exemple


Ok, maintenant je ne comprends tout simplement pas la question. Vous avez deux classes dans la même assemblée et vous voulez que l'un d'entre eux ne pas hériter d'un autre. Ok, alors qu'est-ce que tu as besoin de nous? C'est ton code; Ecrivez-le cependant que vous voulez! Vous n'avez pas besoin d'un mot-clé spécial pour vous empêcher de faire quelque chose que vous savez que vous n'êtes pas censé.


duplicaté possible de Comment puis-je créer une classe A en C #, où une ne peut être hérédirée que par b, c, d?


3 Réponses :


9
votes

Aussi loin que je sache, en utilisant interne est le seul moyen de contrôler qui peut hériter d'une classe. Si les héritiers doivent être dans un assemblage différent, vous pouvez laisser des classes d'un autre assembly voir les internes de votre assembly à l'aide de internealalsvisibleto attribut (l'ensemble cible doit être signé pour que cela fonctionne avec des assemblys signés).


2 commentaires

Bonne réponse, mais vous n'avez pas besoin de signer pour les internesVissibleto au travail.


@Andy merci d'avoir clarifié. J'ai oublié de mentionner que la signature n'est requise que pour les assemblys signés. J'ai décidé de mentionner la signature en premier lieu, car je me souviens des problèmes que je suis allé pour savoir pourquoi je ne pouvais pas tester des méthodes internes de mon assemblage signé à partir de mon ensemble de tests d'unité non signés.



20
votes

Y a-t-il un moyen de permettre à certaines classes d'hériter de cette classe?

oui. Si le code héritant est cartographié partiellement vous pouvez mettre une demande de héritage sur la classe de base et que l'exécution ne permettra pas la classe héritante de charger s'il ne remplit pas les conditions. de la demande:

https://msdn.microsoft. com / fr-US / bibliothèque / x4yx82e6 (v = vs.100) .aspx

Bien sûr, Full Trust signifie Full Trust . Le code entièrement fiable peut hériter de ce qu'il veut.

Je soupçonne que vous essayez d'imposer des restrictions que vous ne devriez vraiment pas essayer d'imposer. Pouvez-vous décrire pourquoi vous essayez de faire cette chose difficile? Il y a probablement une meilleure façon de faire ce que vous voulez.

mise à jour:

J'essaie de limiter l'héritage au sein de mes classes dans la même assemblée.

Ensuite, vous auriez probablement dû dire qu'en premier lieu.

Faites tous les constructeurs de la classe interne. Afin d'hériter d'une classe, il doit avoir un constructeur accessible. Si vous effectuez tous les constructeurs internes, seules les classes de cet ensemble peuvent hériter de la classe de base.


1 commentaires

Joli. Bien que je ne puisse pas l'utiliser parce que je suis sur .NET 3.5



0
votes

Une astuce parfois utilisée est de déclarer des constructeurs privés. De cette façon, vous pouvez réaliser:

public class A
{
     private A(){}

     // Here B can inherit from A
     public class B : A{}

 }

 // This is not allowed
 public class C : A{}


0 commentaires