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.
Related
I'm currently looking at some old code and I've come across a class that is using a private static property which is created with a default value and never modified; something like this -
public class Foo
{
private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ToString();
public Bar GetBar(int barId)
{
// get bar using "ConnectionString" above
}
}
So my question is - Is there any benefit to ConnectionString being static? i.e. Is ConfigurationManager.ConnectionStrings["SqlConnection"].ToString(); run every time new Foo() is run thus making the static value of the property redundant as it is overwritten every time the class is initialised?
Static fields are initialized once when the first object of that class is instantiated, not every time an object is created. That makes them relatively efficient.
However, there is a downside to this, and that is that the instance-level constructors are embellished with a state machine which determines whether the one-time initialization has been completed or not.
When the first object of the class is being created, the static constructor will be invoked before any other code executes on an instance level. For subsequent instantiations, this step will be skipped, because the class has already been initialized.
This additional code, which is generated during the compilation, makes every instance-level constructor a tiny bit slower than it would otherwise be without the static members.
No, static members are initialized only once before the class is referenced for the first time in your program and it remains in memory for the lifetime of the application domain.
But in this case the field is redundant because the ConfigurationManager caches this value anyway, so doesn't read it from the configuration file everytime you access it.
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.
Considering the 'standard' C# implementation of a singleton pattern with type initialisation:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance
{
get
{
return instance;
}
}
private Singleton() { }
}
Is there any point in the static property? If the static field is marked as readonly, then surely it cannot be written to from anywhere, including from outside the class. For a more terse implementation, would this work?:
public sealed class Singleton
{
public static readonly Singleton Instance = new Singleton();
private Singleton() { }
}
It seems fine to me but I've only ever seen the top one used so I wonder if there is anything wrong that I have missed.
Is there any point in the static property?
Yes. It hides the implementation detail that the value is retrieved from a field in the exact same class. If you expose the field, you're stuck with that implementation forever (assuming you can't later change/rebuild all code referring to it). If you use a property, you could later:
Change to use Lazy<T>
Use a field within a nested class to get potentially lazier initialization if you want to have other static methods in the class
Use some new and funky scheme yet to be devised
Basically, with a property you've got options for future change. With a field, you haven't.
I used not to think this was a relevant difference, but in Noda Time I've had situations where complex type initialization ordering issues have made it really important that I can control this sort of thing. Where I've exposed a public static readonly field in an earlier version, I've later regretted it :(
A public static readonly field works in terms of still being a singleton - it just gives you less control.
As an aside, you may wish to add an empty static constructor to your class. See my articles on singleton implementations and beforefieldinit for more details.
In case of the Singleton pattern it's not very harmful to have a public readonly field rather than just a getter.
The reason the 'standard' implementation is using a getter is to be consistent with the rest of public getters and make you adopt good habits for all the other cases where a getter is more appropriate than a poublic field (for adding functionality without changing the interface for example)
Readonly will mean that it is an instance variable that cant be written to, static is a variable that can be read without instantiating the object. For example you would call them as follows:
//Readonly
var readonlySingleton = new singleton();
var result = readnlySingleton.Instance;
//static readonly
var result = singleton.Instance;
I have a class with a static constructor:
private static readonly Dictionary<string, User> UsersByName;
private static readonly Dictionary<string, User> UsersByEmail;
static MyClass() {
List<User> users = GetUsers();
UsersByName = users.ToDictionary(user => user.Name);
UsersByEmail = users.ToDictionary(user => user.Email);
}
private static List<User> GetUsers() { /* Make a WCF service call */ }
My problem was that whenever I made that WCF call, all of the worker threads in this web application died. After a lot of head scratching and binary chopping I found the root cause - it happened when we added UsersByEmail, and moved the code into a static constructor. Changing the code to the following fixed everything.
private static readonly List<User> AllUsers = GetUsers();
private static readonly Dictionary<string, User> UsersByName = AllUsers.ToDictionary(user => user.Name);
private static readonly Dictionary<string, User> UsersByEmail = AllUsers.ToDictionary(user => user.Email);
private static List<User> GetUsers() { /* Make a WCF service call */ }
Leaving aside the bad design of calling WCF from a static constructor (which break the app until it's restarted if the service happens to be down), because that is temporary code - I'm trying to find out why the change fix this problem. I ran it in the debugger many times, with the only difference being me adding or removing an empty static constructor; the call stack is always the same meaning the web service is called at the same time, so I don't see how being called from a class without a static constructor could make any difference.
As I recall, beforefieldinit tells the JIT compiler that the static constructor can be run at any point before any static fields are referenced.
So, for example, if the class was first accessed inside a for loop, the JIT might try to instantiate it statically before the for loop begins, so it doesn't have to include code inside the for loop to check whether it's been instantiated during each iteration. Likewise, it's possible for a static method to be called without actually initializing any of the static properties, if the method doesn't touch any of those properties.
But if you include an explicit static constructor, it sets beforefieldinit to false, meaning the JIT-compiled code will wait until that point in the for loop where the class gets accessed before instantiating the class, and it will instantiate it at that point, regardless of whether the code actually touches any of the static fields.
So the short answer is, yes, it could have an impact on the order in which your code gets run, but it's pretty rare for it to cause problems, and I don't know why it would make a difference in this particular case.
See Jon Skeet's answer for more details.
What are the benefits of having a member variable declared as read only? Is it just protecting against someone changing its value during the lifecycle of the class or does using this keyword result in any speed or efficiency improvements?
I don't believe there are any performance gains from using a readonly field. It's simply a check to ensure that once the object is fully constructed, that field cannot be pointed to a new value.
However "readonly" is very different from other types of read-only semantics because it's enforced at runtime by the CLR. The readonly keyword compiles down to .initonly which is verifiable by the CLR.
The real advantage of this keyword is to generate immutable data structures. Immutable data structures by definition cannot be changed once constructed. This makes it very easy to reason about the behavior of a structure at runtime. For instance, there is no danger of passing an immutable structure to another random portion of code. They can't changed it ever so you can program reliably against that structure.
Robert Pickering has written a good blog post about the benefits of immutability. The post can be found here or at the archive.org backup.
The readonly keyword is used to declare a member variable a constant, but allows the value to be calculated at runtime. This differs from a constant declared with the const modifier, which must have its value set at compile time. Using readonly you can set the value of the field either in the declaration, or in the constructor of the object that the field is a member of.
Also use it if you don't want to have to recompile external DLLs that reference the constant (since it gets replaced at compile time).
There are no apparent performance benefits to using readonly, at least none that I've ever seen mentioned anywhere. It's just for doing exactly as you suggest, for preventing modification once it has been initialised.
So it's beneficial in that it helps you write more robust, more readable code. The real benefit of things like this come when you're working in a team or for maintenance. Declaring something as readonly is akin to putting a contract for that variable's usage in the code. Think of it as adding documentation in the same way as other keywords like internal or private, you're saying "this variable should not be modified after initialisation", and moreover you're enforcing it.
So if you create a class and mark some member variables readonly by design, then you prevent yourself or another team member making a mistake later on when they're expanding upon or modifying your class. In my opinion, that's a benefit worth having (at the small expense of extra language complexity as doofledorfer mentions in the comments).
To put it in very practical terms:
If you use a const in dll A and dll B references that const, the value of that const will be compiled into dll B. If you redeploy dll A with a new value for that const, dll B will still be using the original value.
If you use a readonly in dll A and dll B references that readonly, that readonly will always be looked up at runtime. This means if you redeploy dll A with a new value for that readonly, dll B will use that new value.
There is a potential case where the compiler can make a performance optimization based on the presence of the readonly keyword.
This only applies if the read-only field is also marked as static. In that case, the JIT compiler can assume that this static field will never change. The JIT compiler can take this into account when compiling the methods of the class.
A typical example: your class could have a static read-only IsDebugLoggingEnabled field that is initialized in the constructor (e.g. based on a configuration file). Once the actual methods are JIT-compiled, the compiler may omit whole parts of the code when debug logging is not enabled.
I have not checked if this optimization is actually implemented in the current version of the JIT compiler, so this is just speculation.
Keep in mind that readonly only applies to the value itself, so if you're using a reference type readonly only protects the reference from being change. The state of the instance is not protected by readonly.
Surprisingly, readonly can actually result in slower code, as Jon Skeet found when testing his Noda Time library. In this case, a test that ran in 20 seconds took only 4 seconds after removing readonly.
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/
Don't forget there is a workaround to get the readonly fields set outside of any constructors using out params.
A little messy but:
private readonly int _someNumber;
private readonly string _someText;
public MyClass(int someNumber) : this(data, null)
{ }
public MyClass(int someNumber, string someText)
{
Initialise(out _someNumber, someNumber, out _someText, someText);
}
private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
//some logic
}
Further discussion here: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx
Adding a basic aspect to answer this question:
Properties can be expressed as readonly by leaving out the set operator. So in most cases you will not need to add the readonly keyword to properties:
public int Foo { get; } // a readonly property
In contrast to that: Fields need the readonly keyword to achieve a similar effect:
public readonly int Foo; // a readonly field
So, one benefit of marking a field as readonly can be to achieve a similar write protection level as a property without set operator - without having to change the field to a property, if for any reason, that is desired.
Be careful with private readonly arrays. If these are exposed a client as an object (you might do this for COM interop as I did) the client can manipulate array values. Use the Clone() method when returning an array as an object.
Another interesting part of usage of readonly marking can be protecting field from initialization in singleton.
for example in code from csharpindepth:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
readonly plays small role of protecting field Singleton from being initialized twice. Another detail is that for mentioned scenario you can't use const because const forces creation during compile time, but singleton makes creation at run time.
If you have a pre defined or pre calculated value that needs to remain same through out the program then you should use constant but if you have a value that needs to be provided at the runtime but once assigned should remain same throughout the program u should use readonly. for example if you have to assign the program start time or you have to store a user provided value at the object initialization and you have to restrict it from further changes you should use readonly.
readonly can be initialized at declaration or get its value from the constructor only. Unlike const it has to be initialized and declare at the same time.
readonly has everything const has, plus constructor initialization
code https://repl.it/HvRU/1
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine(new Test().c);
Console.WriteLine(new Test("Constructor").c);
Console.WriteLine(new Test().ChangeC()); //Error A readonly field
// `MainClass.Test.c' cannot be assigned to (except in a constructor or a
// variable initializer)
}
public class Test {
public readonly string c = "Hello World";
public Test() {
}
public Test(string val) {
c = val;
}
public string ChangeC() {
c = "Method";
return c ;
}
}
}
There can be a performance benefit in WPF, as it removes the need for expensive DependencyProperties. This can be especially useful with collections