Can I make a type "sealed except for internal types"
Asked Answered
S

2

14

I want to make a type that can be inherited from by types in the same assembly, but cannot be inherited from outside of the assembly. I do want the type to be visible outside of the assembly.

Is this possible?

Scotia answered 18/6, 2010 at 18:11 Comment(0)
S
21

You can make the constructor internal:

public class MyClass
{
    internal MyClass() { }
}

Every class that derives from a base class must call a constructor of the base class in its constructor. Since it can't call the constructor if the base class is in a different assembly, the derived class doesn't compile.

Skewness answered 18/6, 2010 at 18:12 Comment(5)
and how do you create an instance outside your assembly?Crofoot
@tanascius: add a factory method, for example?Skewness
yes that's possible, although it is unclear if the OP needs to create instances at all (he talks about visible, only) ... +1Crofoot
public class EvilInternalClass : MyClass { public EvilInternalClass() { } }Interfluent
Note that any static variables/static methods/const values should be marked as internal or private as well.Vexation
E
2

I think this question could still benefit from a semantically correct answer... which is "no". You can't declare a type as "sealed to external assemblies only".

Don't get me wrong: dtb's answer is a good one. An internal constructor is the closest you can get from the desired result.

However, I think that anyone reading this should be aware that in this example, MyClass wouldn't be described as being sealed at runtime. It is unlikely that this will ever be a problem, but if may cause logic based on reflection (from your code or a 3rd party library) to act differently on this particular type. It's something to keep in mind.

And now, to further expand on dtb's sample code:

public class MyClass
{
    internal MyClass() { }

    // This factory method will be accessible from external assemblies, making your class instantiable yet still "sealed"
    public static MyClass Create()
    {
        return new MyClass();
    }
}

This way you can still create instances of MyClass from outside the owning assembly, while still keeping control over inheritance.

Externalize answered 12/10, 2018 at 19:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.