0

Why should this code be allowed to compile?

public abstract class AbstractPrivateBase
{
    private AbstractPrivateBase() { }
}

Inheritors cannot instantiate themselves. Thusly, there is no way to derive from this class. I feel like Visual Studio (or even Resharper) should show an error stating something like, "Abstract classes cannot contain only private constructors." because it makes no sense in the language to allow this.

The only possible use would be if this class contained static members. If that is the case, a friendly warning stating, "Abstract classes with only private constructors can be made static." since there is no way to access any other members than the static ones.

Michael Yanni
  • 1,476
  • 4
  • 17
  • 29
  • 2
    The answer is probably going to be "because the specification doesn't prohibit it", possibly coupled with "because the C# compiler team did not decide to dedicate development cycles to create a warning in this case because there were more important things on the schedule." – Eric J. Jul 16 '15 at 19:15
  • It will fail to compile as soon as you add a class that derives from it. – D Stanley Jul 16 '15 at 19:15
  • http://stackoverflow.com/a/3454399/996081 – cbr Jul 16 '15 at 19:17
  • @cubrr I understand the use of private constructors on abstract classes. The question relates to ONLY having private constructors on abstract classes. – Michael Yanni Jul 16 '15 at 19:19
  • Did you see the code sample? – cbr Jul 16 '15 at 19:21
  • @cubrr Ah, I see it now. Yeah, it is basically the same answer as dasblinkenlight, except I feel his answer is more concise and easier to understand in a general sense since it provides assignment of the private derived classes as public static members. – Michael Yanni Jul 16 '15 at 19:41

1 Answers1

6

This would make perfect sense, if you derive a nested class from that private base:

public abstract class AbstractPrivateBase {
    public static AbstractPrivateBase D1 = new Derived1();
    public static AbstractPrivateBase D2 = new Derived2();
    public static AbstractPrivateBase D3 = new Derived3();
    private AbstractPrivateBase() { }
    private class Derived1 : AbstractPrivateBase {
    }
    private class Derived2 : AbstractPrivateBase {
    }
    private class Derived3 : AbstractPrivateBase {
    }
}

Classes Derived1 through Derived3 have access to private AbstractPrivateBase() constructor, so this trick effectively restricts derivation to nested classes.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • are there any design patterns that specifically make use of this? – Jonesopolis Jul 16 '15 at 19:20
  • Smart! What a crazy pattern I've never seen or thought of. Definitely marking as the answer. :-) – Michael Yanni Jul 16 '15 at 19:22
  • 2
    @Jonesopolis I cannot think of a named design pattern for this specific implementation, but you can use this approach when you need very tight control over derivation. Something like that could be used to model Java's smart `enum`s in C#. – Sergey Kalinichenko Jul 16 '15 at 19:24
  • Now that you present this, I have seen it before somewhere. It can be used to implement the factory pattern. Somehow the name "Skeet" is associated with that faint recollection. – Eric J. Jul 16 '15 at 19:29