Private vs Static constructors in .Net - c#

I searched for this a lot, but none of the answers are clear (at-least for me!). Now I'm putting this question in SO, as I believe I can't get a more clarified answer anywhere else.
When should I use a private/static constructor in my class?
I'm fed up of usual answers, so please help me with some real-time examples and advantages/disadvantages of using these constructors.

Static constructors: used for initialising static members.
Private constructors: used when you only want a class to be instantiated from within its own code (typically in a static method). For example:
public class Thing
{
static int Number;
static Thing()
{
Number = 42; // This will only be called once, no matter how many instances of the class are created
}
// This method is the only means for external code to get a new Thing
public static Thing GetNewThing()
{
return new Thing();
}
// This constructor can only be called from within the class.
private Thing()
{
}
}

When should I use a private constructor in my class?
When you want a constructor, but don't want to expose it to the world. This could be because you have a factory method that calls the constructor (after validation), or because that constructor is called by ctor-chaining (i.e. public Foo(string) : this() { ...}).
Additionally, note that reflection code is often able to use a private constructor - for example serialization or ORM libraries.
Also, in early C# compilers, when you are writing what would now be a static class - having a private constructor was the only way of making it appear uncreatable.
When should I use a static constructor in my class?
When you need to initialize some static state prior to that state being accessed by instances or static methods.

Static constructor is used to intialize the static members of the class and is called when the first instance of the class is created or a static member is accessed for the first time.
Private constructor is used if you have overloads of the constructor, and some of them should only be used by the other constructors

Related

Why must a static constructor be parameterless?

I'm encountering this error:
'LnkScript.LnkScript.KillstreakHud.KillstreakHud(InfinityScript.Entity)': a static constructor must be parameterless C:\Users\home\Desktop\LnkScripts.cs 61 20 LnkScript
My source code:
public class KillstreakHud : BaseScript
{
static KillstreakHud(Entity player)
{
string killstreak = "^3Killstreak:^3" + player.GetField<int>("killstreak").ToString();
HudElem hudelem = HudElem.CreateFontString(player, "hudsmall", 1f);
HudElem.SetPoint("TOPCENTER", "TOPCENTER");
HudElem.SetText(killstreak);
base.OnInterval(300, delegate
{
killstreak = "^3Killstreak:^3" + player.GetField<int>("killstreak").ToString();
hudelem.SetText(Killstreak);
return true;
});
}
}
Clearly, my static constructor is not parameterless, and the compiler takes umbrage at this fact. But why?
A static constructor must be parameterless because nothing ever calls it, it is invoked when you access a static member or create an instance of the class, but not directly (it is called by the runtime).
The solution: Remove your parameters, or make it non-static
Reference for static constructors: http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
To make it non-static (note that it will need to be invoked directly with the new keyword now):
public KillstreakHud(Entity player)
{
...
}
In my opinion this is a limitation of the language. Static is something that is called once and does not change. There is no reason (apart from not implemented) why it cannot accept a parameter with the understanding that it will only ever use the parameter value once.
This limitation of the language is what has made such a mess in "public static class ConfigurationManager"
There are lost of people asking can I use a different config file?
If the constructor could accept a parameter then this would be easy
(but it can't so you have to make your own config)
The main purpose of declaring a data member static is that it should be available in all instances of the class. When a data member is shared among different instances it is imperative that data should be consistent among all the instances of the class.
And also there is no way to call static constructor explicitly.
Therefore the purpose of having a parameterized static constructor is useless.
a static constructor is implicitly called when:-
1. static data member is referenced.
or
2.object of the class containing static constructor is created.
visit https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

Data initialization over static or public constructor

I'd like to know if there is a drawback initializing data over a static constructor instead of a public constructor. I assume that the first two code snipers do the same.
a short example below
class Test
{
private readonly static Dictionary<string, string> languages =
new Dictionary<string,string>()
{
{"de-CH", "Language.German".Translate()},
{"fr-CH", "Language.French".Translate()},
{"it-CH", "Language.Italian".Translate()}
};
}
or
class Test
{
private readonly static Dictionary<string, string> languages =
new Dictionary<string,string>();
static LanguageChangeFragment()
{
languages.Add("de-CH", "Language.German".Translate());
languages.Add("fr-CH", "Language.French".Translate());
languages.Add("it-CH", "Language.Italian".Translate());
}
}
or using a public constructor
class Test
{
private readonly Dictionary<string, string> languages =
new Dictionary<string,string>();
public LanguageChangeFragment()
{
languages.Add("de-CH", "Language.German".Translate());
languages.Add("fr-CH", "Language.French".Translate());
languages.Add("it-CH", "Language.Italian".Translate());
}
}
Edit:
Changed removed static in last snipper, so that no exception is thrown when creating a new Test instant
The main problem with using the public constructor is that the normal public constructor is executed every time an object of class Test is created. This would cause the static languages dictionary to grow each time you created an instance of Test. In this example however, the second instance of Test would throw an ArgumentException because a dictionary requires that all keys are unique.
As for the options you show for initialization using a static constructor or where you declare the static member, the compiled code is very similar, since the first time a variable of type Test is declared, this code will run and populate your dictionary.
Keep in mind that the static constructor will run after all static members are initialized.
EDIT
The question was updated to make the dictionary an instance member in the last example.
The main difference between these examples now is in the use of memory and adaptability. If there is a dictionary instance that is a member of each instance of Test, a large number of instances will use more memory. That may be what is required here, especially if an instance of Test might need to adapt the contents of the dictionary, but not affect other instances. If the dictionary will always contain the same elements in all instances of Test, then it would make sense to make the dictionary static - and let all instances share the same dictionary in memory.
I think first you have to understand the characteristics of each.
From MSDN:
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.
A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.
So just by thinking about the above, ask yourself many questions, for instance:
Is it expensive to initialize this constructor? If so, maybe I need to control when it is initialized, which I will not be able to do with a static constructor.
Do I need to access this object via multiple threads? If so, I can get myself into trouble using the normal public constructor. Same for unmanaged code.

C# static class why use? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When to Use Static Classes in C#
I set my classes as static a lot, but I am not sure when use static or not, or what's the difference it makes to use it or not.
can anybody explain please?
Making a class static just prevents people from trying to make an instance of it. If all your class has are static members it is a good practice to make the class itself static.
If a class is declared as static then the variables and methods need to be declared as static.
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.
Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.
->The main features of a static class are:
They only contain static members.
They cannot be instantiated.
They are sealed.
They cannot contain Instance Constructors or simply constructors as we know that they are associated with objects and operates on data when an object is created.
Example
static class CollegeRegistration
{
//All static member variables
static int nCollegeId; //College Id will be same for all the students studying
static string sCollegeName; //Name will be same
static string sColegeAddress; //Address of the college will also same
//Member functions
public static int GetCollegeId()
{
nCollegeId = 100;
return (nCollegeID);
}
//similarly implementation of others also.
} //class end
public class student
{
int nRollNo;
string sName;
public GetRollNo()
{
nRollNo += 1;
return (nRollNo);
}
//similarly ....
public static void Main()
{
//Not required.
//CollegeRegistration objCollReg= new CollegeRegistration();
//<ClassName>.<MethodName>
int cid= CollegeRegistration.GetCollegeId();
string sname= CollegeRegistration.GetCollegeName();
} //Main end
}
Static classes can be useful in certain situations, but there is a potential to abuse and/or overuse them, like most language features.
As Dylan Smith already mentioned, the most obvious case for using a static class is if you have a class with only static methods. There is no point in allowing developers to instantiate such a class.
The caveat is that an overabundance of static methods may itself indicate a flaw in your design strategy. I find that when you are creating a static function, its a good to ask yourself -- would it be better suited as either a) an instance method, or b) an extension method to an interface. The idea here is that object behaviors are usually associated with object state, meaning the behavior should belong to the object. By using a static function you are implying that the behavior shouldn't belong to any particular object.
Polymorphic and interface driven design are hindered by overusing static functions -- they cannot be overriden in derived classes nor can they be attached to an interface. Its usually better to have your 'helper' functions tied to an interface via an extension method such that all instances of the interface have access to that shared 'helper' functionality.
One situation where static functions are definitely useful, in my opinion, is in creating a .Create() or .New() method to implement logic for object creation, for instance when you want to proxy the object being created,
public class Foo
{
public static Foo New(string fooString)
{
ProxyGenerator generator = new ProxyGenerator();
return (Foo)generator.CreateClassProxy
(typeof(Foo), new object[] { fooString }, new Interceptor());
}
This can be used with a proxying framework (like Castle Dynamic Proxy) where you want to intercept / inject functionality into an object, based on say, certain attributes assigned to its methods. The overall idea is that you need a special constructor because technically you are creating a copy of the original instance with special added functionality.

Public constructor and static constructor

I am reading a code in C# that uses two constructors. One is static and the other is public. What is the difference between these two constructors? And for what we have to use static constructors?
static and public are orthogonal concepts (i.e. they don’t have anything to do with each other).
public simply means that users of the class can call that constructor (as opposed to, say, private).
static means that the method (in this case the constructor) belongs not to an instance of a class but to the “class itself”. In particular, a static constructor is called once, automatically, when the class is used for the first time.
Furthermore, a static constructor cannot be made public or private since it cannot be called manually; it’s only called by the .NET runtime itself – so marking it as public wouldn’t be meaningful.
Static constructor runs just once, before your class is instantiated. It's used if you want something to happen just once. A nice example would be a Bus class (similar to something they explain in MSDN article):
public class Bus
{
public static int busNo = 0;
static Bus()
{
Console.WriteLine("Woey, it's a new day! Drivers are starting to work.");
}
public Bus()
{
busNo++;
Console.WriteLine("Bus #{0} goes from the depot.", busNo);
}
}
class Program
{
static void Main(string[] args)
{
Bus busOne = new Bus();
Bus busTwo = new Bus();
}
// Output:
// Woey, it's a new day! Drivers are starting to work.
// Bus #1 goes from the depot.
// Bus #2 goes from the depot.
}
Static Constructor... It is guaranteed to be called "once" througout the life of the application/app Domain. It can contain statements that you want to be executed only once.
Public Constructor... Since we can not add access modifiers to a static constructor, a public constructor means you are talking about an instance constructor. If an instance constructor is public then the outside world can create its instances.
Other options are Internal ( can be called from within the library), Private ( from within the class only).
Static constructor called only the first instance of the class created but the public constructor called every time that instance of the class is created.
Static Constructor
A constructor declared using a static modifier is a static constructor.
A static constructor is used to initialize static data or to perform a
particular action that needs to be performed only once in the life cycle of
class. A static constructor is the first block of code to execute in class.
Static constructor executes one and only one time in the life cycle of
class. It is called automatically. The static constructor does not take
any parameters. It has no access to specifiers. It is not called
directly.
Instance or Public Constructor
Instance constructor is used to initialize instance data. Instance
constructor is called every time when the object of the class is created. It
is called explicitly. Instance constructor takes parameters. It has
access specifiers.
My source: Static Constructor Vs Instance Constructor in C#

When is a static constructor called in C#?

When I have class containing a static constructor, is that constructor called when the assembly containing the class is first loaded or when the first reference to that class is hit?
When the class is accessed for the first time.
Static Constructors (C# Programming Guide)
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
It's not quite as simple as you might expect despite straightforward documentation. Jon Skeet's article http://csharpindepth.com/Articles/General/Beforefieldinit.aspx goes into this question in details.
Summary:
Static constructor is guaranteed to be executed immediately before the first reference to a member of that class - either creation of instance or own static method/property of class.
Note that static initilaizers (if there is no static constructor) guaranteed to be executed any time before first reference to particular field.
The static constructor is called before you use anything in the class, but exactly when that happens is up to the implementation.
It's guaranteed to be called before the first static member is accessed and before the first instance is created. If the class is never used, the static constructor is not guaranteed to be called at all.
In case static method is called from parent class, static constructor will not be called, althogh it is explicitly specified. Here is an example b constructor is not called if b.methoda() is called.
static void Main(string[] args)
{
b.methoda();
}
class a
{
public static void methoda()
{
//using initialized method data
}
}
class b : a
{
static b()
{
//some initialization
}
}
There seems to be a gotcha with static constructors that is answered elsewhere but took a while to digest into a simple explanation. All the docs and explanations claim the static constructor/intializers are "guaranteed" to run before the first class is instantiated or the first static field is referenced. The gotcha comes in when you try to put a static singleton in the class that creates an instance of itself (chicken/egg). In this case the static constructor ends up being called after the instance constructor - and in my case the instance constructor contained code that relied on some static data.
Static constructor called after instance constructor?
Static constructor can run after the non-static constructor. Is this a compiler bug?
(the answer for me was to put the singleton in a separate class or manually initialize the static data in the instance constructor before it is required)

Categories

Resources