The main difference is that the static class cannot even be instantiated. A normal class with private constructor just doesn’t let any code out of the class instantiate it, but it can be instantiated internally, after all its static methods can access this constructor.
This works:
using static System.Console;
public class Program {
public static void Main() {
var instancia = Instancia.Factory();
WriteLine(instancia.GetType());
}
}
public class Instancia {
private Instancia() {}
public static Instancia Factory() => new Instancia();
}
Behold working in the ideone. And in the .NET Fiddle. Also I put on Github for future reference.
This internal instance can be only internally or can be made available externally to anyone who wants to use, so it depends on how it was coded.
It is even possible to call this private builder publicly in less orthodox ways, with reflection, for example.
Another difference is that the normal class can have non-static members. And it can even make sense knowing that it can be instantiated.
Just remember that if there is a static constructor in any of the classes, it will be called sometime before its use. The normal constructor of the class will only be called by code. It is possible until a static constructor of the normal class is used to create an internal instance.
A technical detail is that static classes are at the same time sealed
and abstract
, can check this in CIL.
Why prefer static class where it makes sense
If the people involved in the code don’t have to do something crazy, the normal class with private constructor may function as the static class, but it depends on following the convention. It would be much better to ensure this via code. And let’s face it, if you say it is static, it sends the right message of what your intention is.
I believe that people use this technique here and there because C# 1 had no static class, just like Java. There’s no point doing this anymore, unless you have a good reason or want to use some trick that can justify existence.
This "trick" is often used to create the Singleton.
The documentation for CA1053, in the paragraph When to Suppress Warnings, says: "(...)The presence of the constructor Suggests that the type is not a Static type.". It seems to me then that it was intentional not to make it Static, finds some reason for this(in this particular class)?
– ramaral
@ramaral no, but may be require some framework, or have some reason I didn’t see, so I might be wrong. I think it should be static class. I’m not saying that this is the case, but there are people who read "don’t use static class" somewhere and do it, even when it is what you should do :) Ideally these things should be commented. Decisions that run out of normal is what should be in comments.
– Maniero
I thought it was because it was used in XAML. I ran a test with a class with identical purpose, providing a Attached Property, that worked being declared Static.
– ramaral
@ramaral would be good to find an authoritative information.
– Maniero