Is there a way to limit who can inherit a class or interface?
Asked Answered
L

3

17

I wonder if there is a way to limit who can inherit from a class.

  • internal: doesn't allow class to be inherited outside the assembly
  • sealed: class cannot be inherited

Is there a keyword or way to allow only certain classes (let's say from it's own namespace only) to inherit that class?

Also, I do not want this special class to be generic. My concern isn't security but the design in general.

Example of what I want:

  • Class A.
  • Class B inherits from A
  • Class C cannot inherit from A
Leaflet answered 25/12, 2011 at 21:28 Comment(8)
Making a class internal not only prevents outside classes from inheriting, but also from using it. To just prevent external childclasses you need special tricks, such as internal abstract methods, and that doesn't work on interfaces.Inferior
What kind of limit would you like? Did you have a look at the InheritanceDemand? palisade.plynt.com/issues/2006Apr/link-demandBromberg
Note that restricting to a namespace isn't much protection at all, since a rogue assembly could just say namespace Awesome { public class Stolen : Secret {} } and now they can use Awesome.Stolen to access Awesome.Secret.Salto
- Wow - Raymond Chen! I've been reading about you! I love your blog :) My concern isn't security. I'm trying to limit inheritance within my classes in the same assembly.Leaflet
@odyodyodys: Then you probably should have said that in the first place. That is easily done. Make all the constructors internal. Then only classes in the same assembly can inherit, because inheritance requires an accessible ctor.Farnham
@EricLippert sorry about that, I wasn't clear. Edited and added an exampleLeaflet
OK, now I just don't understand the question. You have two classes in the same assembly and you want one of them to not inherit from another. OK, so what do you need us for? It's your code; write it however you want! You don't need a special keyword to prevent you from doing something you know you're not supposed to.Farnham
possible duplicate of How can I create a class A in C#, where A can only be inherited by B, C, D?Kamal
F
21

Is there a way to allow only certain classes to inherit that class?

Yes. If the inheriting code is partially trusted then you can put an inheritance demand on the base class and the runtime will not allow the inheriting class to load if it does not meet the conditions of the demand:

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

Of course, full trust means full trust. Fully trusted code can inherit whatever it wants.

I suspect that you're trying to impose restrictions that you really should not be trying to impose. Can you describe why you're trying to do this difficult thing? There's probably a better way to do what you want.

UPDATE:

I'm trying to limit inheritance within my classes in the same assembly.

Then you probably should have said that in the first place.

Make all the constructors of the class internal. In order to inherit from a class, it must have an accessible constructor. If you make all the constructors internal then only classes in that assembly can inherit from the base class.

Farnham answered 25/12, 2011 at 21:44 Comment(1)
Nice. Although I cannot use it because I'm on .Net 3.5Leaflet
B
10

As far as I know, using internal is the only way to control who can inherit a class. If the inheritors must be in a different assembly, you can let classes from another assembly see internals of your assembly using InternalsVisibleTo attribute (the target assembly must be signed in order for this to work with signed assemblies).

Bolide answered 25/12, 2011 at 21:36 Comment(2)
Good answer, but you don't need to sign for InternalsVisibleTo to work.Mouflon
@Mouflon Thanks for clarification. I forgot to mention that signing is required only for signed assemblies. I decided to mention signing in the first place, because I remember the trouble I went through to find out why I could not test internal methods of my signed assembly from my unsigned unit tests assembly.Bolide
E
2

A trick that is sometimes used is declaring private constructors. That way you can achieve:

public class A
{
     private A(){}

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

 }

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

This comes with it's limitations because only classes declared inside of A can inherit from A. I find this trick very useful to do case distinctions.

Elongation answered 3/5, 2018 at 14:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.