What is the difference between a class having private constructor and a sealed class having private constructor?

18,251

Solution 1

Yes A can be inherited by a nested class, while B cannot be inherited at all. This is perfectly legal:

public class A {
  private A() { }

  public class Derived : A { }
}

Note that any code could create a new A.Derived() or inherit from A.Derived (its constructor is public), but no other classes outside the source text of A can inherit directly from A.

A typical use for something like this is a class with enum-like values but which can have custom behavior:

public abstract class A {
  private A() { }

  public abstract void DoSomething();

  private class OneImpl : A { 
    public override void DoSomething() { Console.WriteLine("One"); }
  }

  private class TwoImpl : A { 
    public override void DoSomething() { Console.WriteLine("Two"); }
  }

  public static readonly A One = new OneImpl();
  public static readonly A Two = new TwoImpl();
}

Solution 2

There is one tiny difference you can get, to do with Code Analysis.

Consider this code:

public class Base
{
    public virtual void Function()
    {
    }
}

public class Derived: Base
{
    public static  Derived Create()
    {
        return new Derived();
    }

    private Derived()
    {
        // Code analysis warning: CS2214 "Do not call overridable methods in constructors".
        Function(); 
    }
}

There is a Code Analysis warning for the Derived constructor, because we are accessing a virtual method from it, which is A Bad Thing.

However, if you make Derived sealed, the Code Analysis warning goes away.

So there's a tiny and contrived difference for you. ;)

Solution 3

Based on the second article if this is the only constructor you will not be able to create an instance of Class A or Class B. Because Class A has a private constructor you cannot derive from it due to its protection level, nor can you derive from B with sealed.

Inheritance (C# Programming Guide)

Derived Class Access to Base Class Members A derived class has access to the public, protected, internal, and protected internal members of a base class. Even though a derived class inherits the private members of a base class, it cannot access those members. However, all those private members are still present in the derived class and can do the same work they would do in the base class itself. For example, suppose that a protected base class method accesses a private field. That field has to be present in the derived class for the inherited base class method to work correctly.

Private Constructors (C# Programming Guide)

A private constructor is a special instance constructor. It is commonly used in classes that contain static members only. If a class has one or more private constructors and no public constructors, then other classes (except nested classes) are not allowed to create instances of this class.

Solution 4

A sealed class can be instantiated but a class with a private constructor can not. They both don't allow inheritance, but that's not the objective of a private constructor.

The reason you use a private constructor is to stop instantiation. This is often used in static factory methods, where you must call MyClass::Create(...) to create an instance.

This has nothing to do with sealing, which stops inheritance. If you use a private constructor to stop inheritance, then you're using the wrong approach. There are ways to get around a private constructor for inheritance.

Share:
18,251
jannagy02
Author by

jannagy02

Updated on June 06, 2022

Comments

  • jannagy02
    jannagy02 about 2 years

    Is there any difference between A and B?

    Class A has private constructor:

    class A
    {
        private A()
        { }
    }
    

    Class B is sealed and has a private constructor:

    sealed class B
    {
        private B()
        { }
    }
    
  • Philip Kendall
    Philip Kendall about 11 years
    Slightly pedantically, I could create any number of instances of either A or B if they had factory methods even if they didn't have any constructors other than those specified.
  • Matthew Watson
    Matthew Watson about 11 years
    Haha! Now that's not contrived in that you might actually want to do that (although not commonly). +1 :)
  • jannagy02
    jannagy02 about 11 years
    You can't derive neither A or B. You can't dervie A because of the private constructor. The question could be: If there is a class with a private constructor is there any difference if you marked it sealed.
  • Harrison
    Harrison about 11 years
    @jannagy02: I was updating that as you were typing your comment :-)
  • Keith Nicholas
    Keith Nicholas about 11 years
    Essentially though, this is just the same as providing other constructors on A, except these are super "fancy" nested class based constructors
  • jannagy02
    jannagy02 about 11 years
    I think its the closest answer.