-1

I am currently trying to get deeper into the .NET framework. I ran across an error while I was wondering if I could create two CommandManagers:

Cannot create an instance of CommandManager because it has no public constructors.

Obviously it means: don't do it, and it might not even make sense to have two of them. Now I came across an other error before with the message:

Cannot create an instance of ... because it is sealed

The effect is the same in prohibiting but what is the difference. Why does one choose a class to have no public constructors vs making it sealed?

EDIT:

Sorry I was ill for a couple of days. Further I mixed two languages: VB and C#. I had two tabs open and overlooked that one was standing on C# and one on VB Code. One class was sealed the other seemed to be NonInheritable. I didn't realize that this is actually the same. Now the error messages make sens.

IronPython Code snippet:

commandManager = CommandManager()

fails with

Cannot create instances of CommandManager because it has no public constructors

while

class MyCommandManager(CommandManager):
    return super(MyCommandManager, self).__init__(*args, **kwargs)()

fails with:

cannot derive from System.Windows.Input.CommandManager because it is sealed

I was mislead by these errormessages and since my google and stackoverflow search returned no answer (naturally because CommandManager is always sealed in C# while always NonInheritable in VB) Further CommandManager seems to be both sealed and having no public constructor.

Johannes Maria Frank
  • 2,747
  • 1
  • 29
  • 38
  • What about a *non-public* constructor? What happens if *extending* a sealed class vs. extending a class without a public constructor? – user2246674 Apr 26 '13 at 20:10
  • 2
    Actually you can create instances of sealed classes. A sealed class just cannot be inherited. http://msdn.microsoft.com/pt-br/library/88c54tsw(v=vs.90).aspx – gustavodidomenico Apr 26 '13 at 20:12
  • 1
    Provide us the snippets of code that you are using. – gustavodidomenico Apr 26 '13 at 20:12
  • 2
    Can you post the *exact* error message, ideally with context? are you sure it wasn't saying that you couldn't *inherit* it? or perhaps that you couldn't `override` a `sealed` method? "Cannot create an instance of ... because it is sealed" makes no sense - I would be very interested (but surprised) to see an example that demonstrates this. – Marc Gravell Apr 26 '13 at 20:12
  • 1
    `Cannot create an instance of ... because it is sealed` that sounds like it is something coming from Castle DynamicProxy, or something, not the CLR / compiler. – vcsjones Apr 26 '13 at 20:15
  • Sealed classes can be instantiated. For instance, string is sealed. Are you sure there's not more to that second error? What statement is provoking it? – Reacher Gilt Apr 26 '13 at 20:16

5 Answers5

12

You seal a class to prevent it from being subclassed. You remove public constructors to prevent a class from being directly instantiated, usually as part of a singleton pattern.

You can, of course, combine both.

Paul Phillips
  • 6,093
  • 24
  • 34
2

Sealed means you cannot inherit from it. That's the difference here. You can still create an instance, but cannot inherit.

AD.Net
  • 13,352
  • 2
  • 28
  • 47
1

The sealed keyword has to do with whether the class can be used as a base class. You can absolutely instantiate a sealed class.

Larsenal
  • 49,878
  • 43
  • 152
  • 220
0

Sealed denotes a class from which subclasses cannot be derived; your second error would have to refer to the inability to create a specific subclassing attempt, not an attempt to create an instance of the sealed class itself.

The main reason for not declaring any public constructors for a class are to control the creation of its instances. This is done in the singleton pattern as noted. This might also be done for a factory pattern implementation. In my game engine I do it for various parsers of shared portions of definition files with multiple versions. Sometimes I make all constructors private; sometimes internal; and sometimes protected to provide different control mechanisms. In none of these cases am I actually enforcing a singleton pattern.

Here is an extract of this usage:

internal abstract class AbstractParser {
  protected TextReader              Reader    { get; set; }
  // etc.
}

internal abstract class MapParser : AbstractParser, IParser<IMapDefinition> {
  public abstract IMapDefinition Parse();
  protected internal MapParser(TextReader reader) : this() { 
    Reader = reader;
  }
  public IMapDefinition Parse(Func<MapHeader, string[], int[][],
    HexsideData[,], List<IHpsPlaceName>, int, IMapDefinition> factory
  ) {
    var header     = ParseMapHeader(1);
    var terrain    = ParseTerrain(header.Size);
    var elevations = ParseElevation(header.Size);
    var feature    = ParseFeatures( header.Size);
    var placeNames = ParsePlaceNames();

    return factory(header, terrain, elevations, feature, placeNames, MaxElevationLevel);
  }
  // etc.
}

internal class MapV1Parser : MapParser {
  internal MapV1Parser(TextReader reader) : base(reader) {}

  public override IMapDefinition Parse() {
    return base.Parse((h,t,e,f,p,xe) => (new MapDefinitionV1(h,t,e,f,p,xe)));
  }
}

internal class MapV2Parser : MapParser {
  private readonly Regex regexHeaderLine3;
  internal MapV2Parser(TextReader reader) : base(reader) {
    regexHeaderLine3  = new Regex(@"^([-]?[0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-1])$",
                                  RegexOptions.None);
  }
  public override IMapDefinition Parse() {
    return base.Parse((h,t,e,f,p,xe) => (new MapDefinitionV2(h,t,e,f,p,xe)));
  }
  protected override Line3 ParseHeaderLine3() {  
    /* Definition override for V3 */
  }
}

This infrastructure allows the selection of the appropriate MapParser after reading the first line as follows:

internal static IParser<IMapDefinition> GetMapParser(TextReader reader) {
  string line = reader.ReadLine();
  short version;
  if (!short.TryParse(line, out version))
    Utils.ThrowInvalidDataException("MapParser",1,"Header","Non-integer version number",null,line);

  switch(version) {
    case 1:   return new MapV1Parser(reader);
    case 2:   return new MapV2Parser(reader);
    default:  Utils.ThrowInvalidDataException("MapParser",1,"Header","Unknown version number",
                null,version);
              return null;
  }
}
Pieter Geerkens
  • 11,775
  • 2
  • 32
  • 52
-1

Some inside data

  • the keyword static is actually sealed abstract class [ClassName]

Where abstract says it must be inherited to use.

Where sealed closes it from inherit, because we all know you cant inherit static

fiinix
  • 142
  • 3
  • 1
    -1 for being misleading. `abstract` doesn't mean you have to inherit it to *use* it, it means you have to inherit it to *instantiate* it. As written, `sealed` and `abstract` are contradictions, rendering the class **unusable**. But phrased correctly, they're complimentary, rendering it **uninstantiateable**. ([ref](http://stackoverflow.com/a/1269034/298754)) – Bobson Apr 26 '13 at 20:34
  • @Bobson: If a class is abstract or sealed, but not static, one may declare a variable of that type. If the class doesn't have any public or protected constructors, there may not be any way for such a variable to ever hold anything other than `null`, but such a variable may be declared nonetheless. By contrast, static class types cannot be used to define storage locations, and are thus more "unusable" than types which are abstract but inheritable, or sealed but instantiable. – supercat Apr 30 '13 at 16:00
  • @supercat - On the one hand, you're correct. A `static class` is effectively a namespace, where it doesn't exist except as a way to reference other things. On the other hand, I consider that a "use" of the class. If it wasn't *specifically* the only use of static classes, I wouldn't quibble. – Bobson Apr 30 '13 at 20:19
  • @Bobson: There is in fact sufficient difference between a static class and a namespace that accessing a static class member may be termed a "use": static classes, including generics, have run-once constructors; further, since declaration of a variable of a type is not sufficient action to force the type to run its static constructor if it has not already done so, accessing a static member of a class is more of a "use" than declaring a variable of that type. Still, the fact that static types disallow variable declarations seems pretty relevant. – supercat Apr 30 '13 at 20:29