Data initialization over static or public constructor - c#

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.

Related

Can static properties return new instances of objects/classes in c#

I am building an application in ASP.NET MVC 4. I am creating a class (similar to Factory type) that will return me instance of my service classes which i have made in BAL Layer. I want to declare static properties in that class and they should return Instance of requested Service Class.
My question is that is it possible that a static propery will return instance of new class because static property will be allocated a memory that will remain throughout the application. I am little confused here, Please explain what happens and what is best way to do so.
Code done so far
public class Factory
{
public static CountryService CountryServiceInstance
{
get
{
return new CountryService(new CountryRepository());
}
}
}
What you should do is write a function the will create the new instances not a get property
public class Factory
{
public static CountryService CreateNewService()
{
return new CountryService(new CountryRepository());
}
}
About your memory concern read Sriram Sakthivel's first comment
More about the Factory pattern here:
http://msdn.microsoft.com/en-us/library/ee817667.aspx
A property in C# is just a method which returns what it should return in its body. In your case, each time you access that property, a new instance of the service will be created.
In case you want only one instance of that service, you might want to store it to the static private variable like this
private static readonly Lazy<CountryRepository> _fact
= new Lazy<CountryRepository>(() => new CountryRepository());
Also, a static properlty never stores something "in the memory throughout the application", but a programmer can do that.
Once again, a property is just a pair of set\get methods, unless you use an automatic property, where there is also a backing field created for the value to store.
A static keyword itself only specifies that a current class member must not be accessed though this keyword, and its value will be shared all across the appdomain (or your application).
your method CountryServiceInstance for each call will always gives you a new instance of CountryRepository.
As you have mentioned, Most of the Factory classes are static which are responsible for creating new object instances. If they give the same object instance none of the factory patterns will serve its intent.
you can undoubtedly proceed with your sinppet..
if you want to quickly validate you can check the created objects hashcode
object.GetHashCode() they will be unique as they are separate objects

Why does it seem as if my static constructor is only executed once?

When I have a static field in my class:
public static int Counter = 0;
With a static constructor:
static Class() {
Counter++;
}
When I create an object of this class and check Class.Counter it shows me 1 which is correct.
But when I create another object of the same class, Class.Counter remains 1.
Why is that?
Because the static constructor is executed only once.
From C# Specification:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
An instance of the class is created.
Any of the static members of the class are referenced.
That is because you are incrementing your counter in static constructor, and it will be executed just once.
static constructor C# - MSDN
A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only.
It is called automatically before the first instance is created or any
static members are referenced.
You can fix it by incrementing in instance constructor like:
class Class
{
public static int counter = 0;
public Class()
{
counter++;
}
}
For thread-safety use Interlocked.Increment(ref counter); instead of counter++
Selman22 has it correct, here is a little more detail:
From MSDN
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only.
It is called automatically before the first instance is >created or any static members are referenced.
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.
If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
Reference url: http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

Private vs Static constructors in .Net

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

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#

private constructor gets empty private static readonly string

I have the following code. Is it not the exact code which I am using since it is internal to my place of work, but is a representation of the scenario which I am encountering.
public class Service : ServiceBase
{
private static readonly Service _instance = new Service();
private static readonly string a = #"D:\test.txt";
private Service () : base()
{
// the value stored in "a" is always blank.
Console.Writeline(a);
}
static void Main(string[] args)
{
Run(_instance);
}
}
This code is a windows service (there is service specific code in the base class). For some reason the value stored in "a" is always blank in the constructor. Is there something obvious which is doing this, or is it a quirk in the .NET platform?
Swap round the declarations of the _instance and a fields. In C#, static fields are initialized in the order in which they're declared. In other words, your Server constructor is running too early.
Or you could declare a as const, which removes it from the construction process.
The problem is that you're calling the constructor before the initializer for a is run, so you're seeing the default value for a. In fact, it's not blank (an empty string) - it's null. You can fix this by reordering:
public class Service : ServiceBase
{
// Initialize a first
private static readonly string a = #"D:\test.txt";
private static readonly Service _instance = new Service();
...
}
The static initializers are run in the textual order (which becomes somewhat undefined with partial classes). From section 10.5.5.1 of the C# 3.0 spec:
The static field variable initializers
of a class correspond to a sequence of
assignments that are executed in the
textual order in which they appear in
the class declaration. If a static
constructor (§10.12) exists in the
class, execution of the static field
initializers occurs immediately prior
to executing that static constructor.
Otherwise, the static field
initializers are executed at an
implementation-dependent time prior to
the first use of a static field of
that class.
I'm not sure I use that would though... it's too easy to break.
Can you change it to const? That would be more robust:
private const string a = #"D:\test.txt";
That way it won't matter if someone changes the order again at a later date, thinking that reordering is a harmless operation. Presumably you were unaware of the importance of the order here, otherwise you wouldn't have asked this question - how willing are you to gamble that another programmer looking at the same code won't have the same issue? :)
Static fields are instantiated in the order they appear in the text file. So your Service is being constructed before the string is initialized. if you swap those two lines it should work.
Link: http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx
Oh, and the singleton pattern is often an anti-pattern. Try to avoid using it if possible.

Categories

Resources