If a class has a private constructor then it can't be instantiated.
So, if I don't want my class to be instantiated and still use it, then I can make it static.
What is the use of a private constructor?
Also, it's used in the singleton class, but except for that, is there any other use?
(Note: The reason I am excluding the singleton case above is that I don't understand why we need a singleton at all when there is a static class available. You may not answer this for my confusion in the question. )
Factory
Private constructors can be useful when using a factory pattern (in other words, a static function that's used to obtain an instance of the class rather than explicit instantiation).
public class MyClass
{
private static Dictionary<object, MyClass> cache =
new Dictionary<object, MyClass>();
private MyClass() { }
public static MyClass GetInstance(object data)
{
MyClass output;
if(!cache.TryGetValue(data, out output))
cache.Add(data, output = new MyClass());
return output;
}
}
Pseudo-Sealed with Nested Children
Any nested classes that inherit from the outer class can access the private constructor.
For instance, you can use this to create an abstract class that you can inherit from, but no one else (an internal constructor would also work here to restrict inheritance to a single assembly, but the private constructor forces all implementations to be nested classes.)
public abstract class BaseClass
{
private BaseClass() { }
public class SubClass1 : BaseClass
{
public SubClass1() : base() { }
}
public class SubClass2 : BaseClass
{
public SubClass2() : base() { }
}
}
Base Constructor
They can also be used to create "base" constructors that are called from different, more accessible constructors.
public class MyClass
{
private MyClass(object data1, string data2) { }
public MyClass(object data1) : this(data1, null) { }
public MyClass(string data2) : this(null, data2) { }
public MyClass() : this(null, null) { }
}
As Stefan, Adam and other have pointed out, private constructors are useful in cases where it is undesirable for a class to be created by code outside of the class. Singletons, factories, static method objects are examples of where being able to restrict constructon of a type is useful to enforce a particular pattern.
To respond to the second part of your question about why singletons are needed if static classes exist: singletons and static classes are not equivalent.
For example, a singleton class can implement an interface, a static class cannot. A singleton object may be passed to methods as a parameter - this is not so easy to do with static classes without resorting to wrapper objects or reflection. There are also cases where you may want to create an inheritance hierarchy in which one (or more) of the leaf classes are singleton - this is not possible with static classes either. As another example, you may have several different singletons and you may want to instantiate one of them at runtime based on environmental or configurational parameters - this is also not possible with static classes.
It is important to understand the language features and choose the right one for the job - they're there for a reason.
Sometimes you shouldn't be able to instantiate a class. This makes this explicit and enforces this at the compiler level.
Singletons are just one use case. Constants classes, static methods classes, and other types of patterns dictate that a class should not be instantiable.
Purpose to create the private constructor within a class
To restrict a class being inherited.
Restrict a class being instantiate or creating multiple instance/object.
To achieve the singleton design pattern.
public class TestPrivateConstructor
{
private TestPrivateConstructor()
{ }
public static int sum(int a , int b)
{
return a + b;
}
}
class Program
{
static void Main(string[] args)
{
// calling the private constructor using class name directly
int result = TestPrivateConstructor.sum(10, 15);
// TestPrivateConstructor objClass = new TestPrivateConstructor(); // Will throw the error. We cann't create object of this class
}
}
You can use it to force a singleton instance or create a factory class.
A static method can call the private constructor to create a new instance of that class.
For example a singleton instance:
public class Foo
{
private Foo (){}
private Foo FooInstance {get;set;}
public static Foo GetFooInstance ()
{
if(FooInstance == null){
FooInstance = new Foo();
}
return FooInstance;
}
}
This allows only one instance of the class to be created.
Well if your only objective is that you don't want it to be instantiated, then making it static is sufficient.
If, otoh, you simply don't want it to be instaniated frm outside the class, (maybe you only want users to get one by using a static factory on the class) - then you need a private ctor to allow those publicly accessible static factories to instantiate it.
Historically, remember that making a class static has not always been around... Making the ctor private was a way to make it not-instantiatable (is this a word? ) before the static keyword could be applied to a class...
Regarding singletons - singleton is a design pattern used when the environment and requirements satisfy similar motivations for the pattern's use; static classes are a language feature.
As LBushkin's answer discusses, while some of the goals of using singleton can be met using static classes, a particular implementation of singleton may exceed the feature set of static classes alone.
If the class ONLY has private constructors, it cannot be instantiated from outside.
You can also have private constructors and public constructors with different signatures.
If you want to create a factory for a class, you can use a private constructur, and add some static "factory" methods to the class itself to create the class.
An example for this is the Graphics class, with the From* methods.
Private constructors is a special instance constructor. and are used in some cases where we create a class which only have static members, so creating instance of this class is useless, and that is where private constructor comes into play.
If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.
example:
class LogClass {
public static double e = Math.E; //2.71828
// Private Constructor:
private LogClass() {
}
}
The declaration of the empty constructor prevents the automatic generation of a parameter less constructor.
If you do not use an access modifier with the constructor it will still be private by default.
Read more: https://qawithexperts.com/tutorial/c-sharp/32/private-constructor-in-c-sharp
Related
I have a factory object ChallengeManager to generate instances of a Challenge object for a game I'm building. There are many challenges. The constructors for each Challenge class derivation are different, however there is a common interface among them, defined in the base class.
When I call manager.CreateChallenge(), it returns an instance of Challenge, which is one of the derived types.
Ideally, I would like to keep the code for the object construction inside the derived class itself, so all the code related to that object is co-located. Example:
class Challenge {}
class ChallengeA : Challenge {
public static Challenge MakeChallenge() {
return new ChallengeA();
}
}
class ChallengeB : Challenge {
public static Challenge MakeChallenge() {
return new ChallengeB();
}
}
Now, my ChallengeManager.CreateChallenge() call only needs to decide the class to call MakeChallenge() on. The implementation of the construction is contained by the class itself.
Using this paradigm, every derived class must define a static MakeChallenge() method. However, since the method is a static one, I am not able to make use of an Interface here, requiring it.
It's not a big deal, since I can easily remember to add the correct method signature to each derived class. However, I am wondering if there is a more elegant design I should consider.
I really like the pattern you are describing and use it often. The way I like to do it is:
abstract class Challenge
{
private Challenge() {}
private class ChallengeA : Challenge
{
public ChallengeA() { ... }
}
private class ChallengeB : Challenge
{
public ChallengeB() { ... }
}
public static Challenge MakeA()
{
return new ChallengeA();
}
public static Challenge MakeB()
{
return new ChallengeB();
}
}
This pattern has many nice properties. No one can make a new Challenge because it is abstract. No one can make a derived class because Challenge's default ctor is private. No one can get at ChallengeA or ChallengeB because they are private. You define the interface to Challenge and that is the only interface that the client needs to understand.
When the client wants an A, they ask Challenge for one, and they get it. They don't need to worry about the fact that behind the scenes, A is implemented by ChallengeA. They just get a Challenge that they can use.
You're "decentralizing" the factory, such that each subclass is responsible for creating itself.
More commonly you would have a central factory that would know about the possible subtypes and how to construct them (often enough, simply by creating a new instance and returning that instance typed as a common interface or common base class). That approach avoids the issue you currently have. I also see no benefit to your current approach. You are currently gaining no encapsulation or code reuse over the more typical implementation of a factory.
For additional reference, have a look at
http://www.oodesign.com/factory-pattern.html
Not necessarily the answer you are looking for but...
You can use following implementation, if you can move away from static method per class.
using System;
public class Test
{
public static void Main()
{
var c1 = ChallengeManager.CreateChallenge();
var c2 = ChallengeManager.CreateChallenge();
//var c = ChallengeManager.CreateChallenge<Challenage>(); // This statement won't compile
}
}
public class ChallengeManager
{
public static Challenage CreateChallenge()
{
// identify which challenge to instantiate. e.g. Challenage1
var c = CreateChallenge<Challenage1>();
return c;
}
private static Challenage CreateChallenge<T>() where T: Challenage, new()
{
return new T();
}
}
public abstract class Challenage{}
public class Challenage1: Challenage{}
public class Challenage2: Challenage{}
This question already has answers here:
Static Method of a Static Class vs. Static Method of a Non-Static Class ( C# )
(6 answers)
Closed 9 years ago.
What is difference between static class vs class with only static methods (and for example private constructor)?
Say we have:
using System;
public class Test
{
public static void Main()
{
Info.SetName("nnn");
Console.WriteLine(Info.Name);
Info.SetName("nn2");
Console.WriteLine(Info.Name);
Info2.SetName("nnn");
Console.WriteLine(Info2.Name);
Info2.SetName("nn2");
Console.WriteLine(Info2.Name);
}
}
public class Info
{
public static string Name;
public static void SetName(string name){
Name = name;
}
}
public static class Info2
{
public static string Name;
public static void SetName(string name){
Name = name;
}
}
So from points of methods/properties access performance, code readabilety, code extendability?
A static class enforces all members to be static and prevents any instance from being created.
From MSDN:
A class can be declared static, indicating that it contains only
static members. It is not possible to create instances of a static
class using the new keyword. Static classes are loaded automatically
by the .NET Framework common language runtime (CLR) when the program
or namespace containing the class is loaded.
You can read more about static classes and members here - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
A static class will require that all methods in that class be static, while a regular class with static methods could also have instance methods.
From a performance standpoint, static methods are slightly faster, because they do not introduce the overhead of checking for the actual instance of an object.
From a redability standpoint, static methods are generally easier to read, but may not be appropriate either, take the following for instance:
DAL.SavePerson();
vs.
var myRepository = new SqlRepository();
myRepository.SavePerson();
Static class - Such a class cannot be instantiated. Also all the members of this class needs to be static. You will declare a class as static when you do not want a class to be instantiated again and again and want to use the object across the project. For example if you want to create a LOGGING functionality. For this you can create a static logging class and put all the (static)functionality into it for instance write method.
Non static class with static members - This class can be instantiated. Also this class can contain both static and non static members which can accessed by classname.xyz() or classname.property .You create this class when you need to create an object(class) that has some functionality(methods) that needs to be used across the application for this you might not always want to create an object of the class and access it(method). For example Redirect to home method in Navigation class.
I guess this explains most of it.
Well, if you declare the class as static, then the compiler can enforce for you that you didn't add any instance members and will also ensure that instances are never created (a non-static class with only static members and a private constructor can still have instances created inside one of the static methods!)
Thus, this is legal for a non-static class:
class Foo {
private Foo() { }
public static Foo Create() { return new Foo(); }
}
But would not be legal for a static class.
For static class you CANNOT create an instance; other case, you can always create one even if all the members and fields are static.
You can't create static class instance.
It's possible to create an instance of a class which only has static methods (unless you hide the constructor).
It's not possible to create an instance of a static class, and the compiler will enforce this.
Short answer, a static class can only contain static methods. A non-static class does not have that explicit restriction and can contain both static and non-static methods.
Long answer: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
static class is used when creating an instance of the class would be meaningless. For example static class HelperMethods vs class HelperMethods
HelperMethods.DoSomething(); // makes sense
new HelperMethods(); // absolutely no use if only contains static methods
Access performance: Almost no difference.
Code readability: It's more readable to use the static modifier when the class shouldn't be instantiated, since that shows how the class is intended to be uses. Also, it adds compile-time checks to prevent using it in wrong ways by mistake.
Code extendability: No difference (regarding static members at least - of course you can extend the class with none-static members if you don't use the static modifier, but with the static modifier the class is implicitly sealed)
Additional note: Extension methods can only be declared in a static class.
Technically you can create a instance of nonstaric class with static methods only: even if the constructor is private, you can do it by means of reflection (or within static methods of the class). You can also create a derived class from that kind of class unless it declared as sealed.
Static class is always abstract (so you by no means can't create an isntance of it) and sealed (you can't create a derived class as well). So static class is a shortcut for abstract sealed class.
Type tp = typeof(Info2); // <- Info2 is static class
if (tp.IsAbstract && tp.IsSealed) { // <- And it is...
...
I'm writing an application in C# for which I need a singleton object; so there'll only be one object of that class. But that class needs to have a list of references to objects of another class of the system, so I added such a list as an attribute and then created a method to add another object to it.
I thought it to be correct but I'm getting an error where a parameter type (the class to be in the list) is less accessible than a method (AddNew in the following code).
Here is what I have so far:
namespace One {
public sealed class Singleton {
// Only instance of the class:
private static readonly Singleton instance = new Singleton ();
private List<MyOtherClass> list;
static Singleton() { }
private Singleton() {
list = new List<MyOtherClass>();
}
// Accessor to the property (the instance per se):
public static Singleton Instance {
get {
return instance;
}
}
// Method to add a new object to the list:
public void AddNew(MyOtherClass newObject) {
list.Add(newObject);
}
}
}
The class whose objects are to be inside that list is defined as follows:
namespace One {
class MyOtherClass {
... // With private attributes and public constructor and methods.
}
}
Where could the problem be? Is it not possible to accomplish what I wanted? The class is public and resides in the same namespace where the singleton class is defined.
Where could the problem be?
Exactly what the compiler says. MyOtherClass is an internal class (implicitly), but you've included it as a parameter to a public method in a public class, which you can't do.
Options:
Make Singleton internal
Make AddNew internal
Make MyOtherClass public
Note that namespaces are entirely separate to access modifiers - they're irrelevant here.
Your MyOtherClass is internal, but your Singleton.AddNew method is public.
A top-level class is internal by default if you don't specify a protection modifier.
I know this question has been asked over and over, but I can't seem to find good enough answers. So to make it clear what I'm trying to know, I'll split this in two questions:
Why can't interfaces have static method signatures? I'll try to preempt the non-answers asking why in the world I would want to do this with the following: I would want to be able to statically invoke GetDbConnectionType() on SqliteCodeGenerator and MssqlCodeGenerator:
interface ICodeGenerator
{
// this is the method I would like to be static:
string GetDbConnectionType();
}
abstract class CodeGeneratorBase : ICodeGenerator
{
public abstract string GetDbConnectionType();
public void GenerateSomeCode(StringBuilder s)
{
s.AppendLine("var foo = new " + GetDbConnectionType() + "();");
}
}
class SqliteCodeGenerator : CodeGeneratorBase
{
public override string GetDbConnectionType()
{
return "SQLiteConnection";
}
}
class MssqlCodeGenerator : CodeGeneratorBase
{
public override string GetDbConnectionType()
{
return "SqlConnection";
}
}
On the other hand, and this is the matter of this second question, if you know of a good alternative to reach the aforementioned goal, then by all means...
Suppose you could specify in an interface that a type had to have a particular static method... how would you call it? Polymorphism works through instances - whereas static members explicitly don't use instances.
Now, having said that, there's one situation in which I can see static interface members working: generic types. For example:
// This isn't valid code...
public void Foo<T>() where T : ICodeGenerator
{
string type = T.GetDbConnectionType();
}
That would call the static member on the concrete type T.
I've blogged more about this, but I suspect the benefit doesn't justify the complexity.
In terms of alternatives - usually you'd have another interface, and have separate types to implement that interface. That works well in some contexts, but not in others.
#JonSkeet: It's possible to create a static interface member in CIL, so I'm afraid your first statement is misleading. I assume it was omitted from C# as a design choice by the Microsoft team to encourage correct usage of interfaces.
The best way to get this functionality is probably with extension methods, these will allow you to add a method to all inheritors of your interface or to a specific implementation of that interface however you need to write a separate class to hold the implementation of the extension method which (if not planned for) can be easy to lose track of.
Jon's answer covers pretty much everything so my answer only includes a possible work around using the .NET configuration API. It requires a bit of syntax overhead but it does give you static access to the instance.
interface IStorage
{
void Store(string item);
}
static class Storage
{
private static readonly IStorage _instance;
static Storage()
{
var storageTypeString = ConfigurationManager.AppSettings["storageTypeString"];
var storageType = Type.GetType(storageTypeString, true);
_instance = (IStorage)Activator.CreateInstance(storageType);
}
public static void Store(string item)
{
_instance.Store(item);
}
}
It might be somewhat helpful if an interface could specify a static class, such that members of that class would be seen by the compiler as static members of that interface. Thus, instead of having to use static class Enumerable<T> to get Enumerable<T>.Default, one could instead syntactically specify IEnumerable<T>.Default.
It would be even more helpful if an interface could specify that some such static methods should be usable in a fashion similar to extension methods, but without the weird scoping rules associated with them (so an interface could appear to offer multiple "convenience" overloads for some member functions without requiring all of the implementations to provide them).
It would be extremely helpful if, combined with such a feature, interface methods could be declared "optional", such that when an implementation provided a method it would be used, and when it did not the extension-ish method would be automatically substituted. This would probably require changes to the CLR, however.
In any case, because interfaces do not include static classes, the best one can do is provide static classes which users of the interface will find helpful, even though the compiler will regard those classes and the interfaces as entirely independent entities.
I know this is old, but actually you can with static functions declared in a static class outside of a name space.
but they way your putting it you would just make the function static in the abstract class
to do it from an interface you do this
public static class Interfacefunction{
public static string GetDbConnectionType(this ICodeGenerator me)
{
// this is the method I would like to be static:
// you can even get access to me
return "SQLiteConnection";
}
}
A sort of workaround (though it may actually be better this way) for this I've decided to use is to use a static instance instead of a static interface.
Rather than:
// does not compile
ISomeInterface {
static void DoSomething();
static bool TestSomething(string pValue);
// etc...
}
static class SomeStaticClass : ISomeInterface {
public static void DoSomething() {
}
public static bool TestSomething(string pValue) {
}
}
Define a class (make it generic if the logic must vary between classes that you use it with):
sealed class SomeClass {
public void DoSomething() {
// reusable implementation
}
public bool TestSomething(string pValue) {
// reusable implementation
}
}
and give a static instance of that class to your static class:
static class SomeStaticClass {
static readonly SomeClass sSomeClass = new SomeClass();
}
The only issue is that you have to decide whether to expose a property to the static instance:
static class SomeStaticClass {
static readonly SomeClass sSomeClass = new SomeClass();
public static SomeClass SomeProperty { get { return sSomeClass; } }
}
...
SomeStaticClass.SomeProperty.DoSomething();
if (SomeStaticClass.SomeProperty.TestSomething(someValue))
...
or to wrap its methods:
static class SomeStaticClass {
static readonly SomeClass sSomeClass = new SomeClass();
public static void DoSomething() {
sSomeClass.DoSomething();
}
public static bool TestSomething(string pValue) {
sSomeClass.TestSomething(pValue);
}
}
...
SomeStaticClass.DoSomething();
if (SomeStaticClass.TestSomething(someValue))
...
When I create utility classes I typically create a class that has a private constructor and exposes all of it's methods and properties as static. What's the best approach for this? What's the difference between the way I do or creating a static class?
Static classes are automatically sealed, so people can't inherit and override their behavior.
That is the only real difference (unless there is something special in the IL)
So if you use a static class, you save yourself the trouble of making the constructor private, and declaring the class sealed.
I would add, that defining a class as static, is "self-documenting" code. Users of your library will know that this class should not be instantiated, and only has static values.
A static class can never be instantiated. No way, no how.
A non-static class with a private constructor but all static methods can be abused in various ways - inheritance, reflection, call the private constructor in a static factory - to instantiate the class.
If you never want instantiation, I'd go with the static class.
Edit - Clarification for FosterZ's comment
Say you have this utility class:
public class Utility
{
public static string Config1 { get { return "Fourty Two"; } }
public static int Negate(int x) { return -x; }
private Utility() { }
}
If another developer isn't clear on its intent, they could do this:
public class Utility
{
public static string Config1 { get { return "Fourty Two"; } }
public int Config2 { get; set; }
public static int Negate(int x) { return -x; }
private Utility() { }
/// Get an instance of Utility
public static Utility GetUtility()
{
return new Utility();
}
}
Now you have a Frankenstein class. Some of its features require instantiation and some don't. Maybe that's what you want but maybe it's not. You could prevent this with code review, but why not make your intentions explicit in code? Marking the class as static eliminates any possible confusion. You can't instantiate a static class or inherit from it.
In addition to the previous answers: The compiler won't allow non-static members on static classes and produces and error. This may help a little bit to not accidently add non-static members.
you can pass object of a class that has private constructor as a parameter to any method but you can't do the same with static class. This is the major difference.
Also I'm going to go with the private constructor never being called by the static methods. So any initialisation in there would be wasted... But that's just a theory.