Ramesh
Ramesh

Reputation: 13266

Inheritable only inside assembly in C#

In C# Is there way to specify a class to be inherited only by a class present in the same assembly and for other assemblies should behave like a public sealed type.

Upvotes: 16

Views: 3890

Answers (8)

Marc Gravell
Marc Gravell

Reputation: 1062600

I think Eric Lippert gets the defining quotes here:

Upvotes: 19

Andrew Baumher
Andrew Baumher

Reputation: 161

To answer the question 10 years later (I was searching for this same solution, so I figure it'd be useful to write down in case anybody else has the same problem in the future), the issue has since been addressed natively (albeit indirectly), with the "private protected" access modifier, introduced in C# 7.2.

This modifier only allows access if it is within the same assembly, and derived from the base class. Apply it to the constructor, and it cannot be derived outside the current assembly. An aside, if you can get away with "internal" and/or metadata, do it, as this requires C# 7.2, which may break compatibility with older devices or applications. Also note that the error produced by this (cannot access constructor due to protection level) is not the same as you would get trying to derive a sealed class (cannot derive a sealed class), but the end result is the same.

Upvotes: 4

Tony Valenti
Tony Valenti

Reputation: 39

I know this is an old post, but I've found another way that works really good and I wanted to post it for other people.

  1. Make a base class with an internal constructor.
  2. Make your derived classes inherit from the base class and be sealed.

````

public abstract class LockResult {
    internal LockResult() {

    }
}

public sealed class LockSucceededResult : LockResult {
    //Info for when a lock succeeded
}

public sealed class LockFailedResult : LockResult {
    //Info for when a lock failed
}

````

Upvotes: 1

user76035
user76035

Reputation: 1536

You can't do that with language constructs, but try with reflection

public class MyClass{
  public MyClass(){
    if(this.GetType().Assembly != typeof(MyClass).Assembly){
        throw new Exception("Can't derive from this type!");
  }
}

Checked it up. Seems to be working. The only problem is that unless somebody reads documentation, the trouble is known at runtime.

Upvotes: 1

Michael Meadows
Michael Meadows

Reputation: 28416

The language itself doesn't have anything that makes this easy, but you should be able to do this by making your constructors internal. If you do this, however, you won't be able to new it up from external assemblies, so you'll have to add a factory method.

public class Foo
{
    internal Foo()
    {
    }

    public Foo Create()
    {
        return new Foo();
    }
}

Here's an alternative that lets you new up the class in external assemblies

public sealed class Foo : FooBase
{

}

public class FooBase
{
    internal FooBase() { }
}

One question you might ask yourself, however, is exactly why you want the class to be sealed. Sometimes it's inevitable, but I have seen the sealed keyword get abused so often that I thought I'd bring it up. Often, developers will seal classes because they are overprotective of their code. Most of the time, if a class is well designed, it doesn't need to be sealed.

Upvotes: 16

G S
G S

Reputation: 36818

No. There is no such provision in the C# language itself. However, workarounds -- as suggested by others here -- may suffice.

Upvotes: 0

Chris Shaffer
Chris Shaffer

Reputation: 32575

The only way I can think would be to use a public wrapper on an internal class, probably with a common interface:

public interface IFoo
{
}

internal class Foo : IFoo
{
}

public sealed class PublicFoo : IFoo
{
    private Foo m_Foo = new Foo();
}

Upvotes: 1

Andrew Arnott
Andrew Arnott

Reputation: 81781

If your class is abstract, there's a very simple way to do it:

public abstract class Foo {
    internal abstract void DoNothing();
    // ... other members
}

Now although your class and most members are public, the internal abstract member makes it impossible to derive from the class outside your assembly.

Upvotes: 5

Related Questions