Static Constructor and singleton - c#

My friend told me that the following is one of the ways to create singleton design pattern in C#
public class class1{
public static class1 Obj { get; private set; }
static class1()
{
Obj = new class1();
}
}
He told me that the static constructor runs only one time in application, so only one instance of class1 will be created,
but I see that I have to add this if(Obj==null) to check the existence of object
public class class1{
public static class1 Obj { get; private set; }
static class1()
{
**if(Obj==null)**
Obj = new class1();
}
}
which code is correct?

Assuming that the only place where Obj is set is in the static constructor, the first code snippet is correct; the second code snippet is redundant.
Since static constructors run only once per class. If there is no other path to set Obj, its value will always be null at the beginning of the static constructor. Therefore, the check if(Obj==null) will always succeed, which makes it redundant.

The static constructor will only ever be called once, at some point prior to the static variables being allocated.
Which means that your friend is correct, you do not need the if statement - it is redundant.
This is because you cannot call a static constructor manually, it will only be called once, at the start of run-time.
Further reading : https://stackoverflow.com/a/4506997/617485

Related

C# Unity > Static instance member not causing constructor to be called

I have noticed a rather weird behaviour in my application I am creating;
I have a class I defined that has a static "instance" variable of the class type.
I would assume that (as per code attached) the constructor would be called.
Alas, it is not, unless I use the Void.get in a non-static field anywhere in my code.
public class Void : TilePrototype {
public static Tile get = new Tile((int)TileEntities.Void);
public static Void instance = new Void();
public Void() {
Debug.Log("created");
id = (int)TileEntities.Void;
isBlocking = true;
register();
}
public override RenderTile render(Tile tile){
return new RenderTile(0, new Color(0, 0, 0, 0));
}
So when I have something like :
public static TileStack empty = new TileStack(Void.get, Void.get);
the Void class constructor never gets called. But, if I have:
Tile t = Void.get;
Anywhere in my code it will be called.
Why?
Thanks.
This is a really really subtle and nuanced area of C#; basically, you've stumbled into "beforefieldinit" and the difference between a static constructor and a type initializer. You can reasonably ask "when does a static constructor run?", and MSDN will tell you:
It is called automatically before the first instance is created or any static members are referenced.
Except... public static TileStack empty = new TileStack(Void.get, Void.get); isn't a static constructor! It is a static field initializer. And that has different rules, which basically are "I'll run when I must, no later, possibly sooner". To illustrate with an example: the following will not (probably) run your code, because it doesn't have to - there isn't anything demanding the field:
class Program
{
static void Main()
{
GC.KeepAlive(new Foo());
}
}
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
}
However, if we make a tiny tweak:
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
static Foo() { } // <=== added this
}
Now it has a static constructor, so it must obey the "before the first instance is created" part, which means it needs to also run the static field initializers, and so on and so on.
Without this, the static field initializer can be deferred until something touches the static fields. If any of your code actually touches empty, then it will run the static field initializer, and the instance will be created. Meaning: this would also have this effect:
class Program
{
static void Main()
{
GC.KeepAlive(Foo.empty);
}
}
public class Foo
{
public static TileStack empty = new TileStack(Void.get, Void.get);
}
This ability to defer execution of the static initialization until the static fields are actually touched is called "beforefieldinit", and it is enabled if a type has a static field initializer but no static constructor. If "beforefieldinit" isn't enabled, then the "before the first instance is created or any static members are referenced" logic applies.
Thanks to Marc Gravell's aswer I came up with this contraption (and admittedly I do like the new solution more than the old one, so thanks again!)
Modifications done to the Void class:
public class Void : TilePrototype {
public static Void instance = new Void();
public static Tile get {
get {
return new Tile(instance.id);
}
}
public Void() {
isBlocking = true;
}
public override RenderTile render(Tile tile){
return new RenderTile(0, new Color(0, 0, 0, 0));
}
}
So as You can see I made the "get" variable a property, so that it's evaluated later, when you actually need the tile, not on construction.
I've changed all "get"s this way.
Second change is in the TilePrototype:
public class TilePrototype {
public static Dictionary<int, TilePrototype> tilePrototypeDictionary = new Dictionary<int, TilePrototype>();
public static void registerPrototype(int id, TilePrototype tp){
tp.id = id;
tilePrototypeDictionary.Add(id, tp);
}
public static bool registered = false;
public static void registerAll(){
if( registered ) return;
registerPrototype(0, Void.instance);
registerPrototype(1, Air.instance);
registerPrototype(2, Floor.instance);
registerPrototype(3, Wall.instance);
(...)
Here I've added the registerPrototype and registerAll functions.
This gives me easy access to all the registered type ids (by say Wall.instance.id) as well as the other way around (from id to instance via the Dictionary)
I also have all registered things in one place, with the possibility of runtime adding more
Overall, much neater, and here I assure that all tiles are registered properly and assigned proper IDs.
Change of ID is simple and in one place and everywhere else, access to this ID is done via a short .instance.id
Thanks again for the help :)

Can a static member variable be used to cache a value in a static class?

I've come across this piece of code where it looks like the original developer has tried to use a static string to cache a value in a static class.
public static class GetStringFromSomeProcess
{
private static string theAnswer;
public static string GetString
{
get
{
if(theAnswer == null)
{
theAnswer = GoGetTheAnswerFromALongRunningProcess();
}
return theAnswer;
}
}
}
As far as I can see this won't work, as you can't instantiate the GetStringFromSomeProcess class, GoGetTheAnswerFromALongRunningProcess will be called every time GetString is used. Am I missing something?
This will work fine - there is only one instance of theAnswer because it is static - and (also because it is static) it can be accessed from a public static property. This means that any changes made to it will be visible to all code that accesses it. So the first call to GetString will set theAnswer to non-null, and subsequent calls will not make a call to GetStringFromSomeProcess().
However, the solution you posted is not threadsafe because GoGetTheAnswerFromALongRunningProcess() could be called simultaneously by multiple threads.
.Net provides the Lazy class to solve this issue, as follows:
public static class GetStringFromSomeProcess
{
private static readonly Lazy<string> _theAnswer = new Lazy<string>(GoGetTheAnswerFromALongRunningProcess);
public static string GetString
{
get
{
return _theAnswer.Value;
}
}
public static string GoGetTheAnswerFromALongRunningProcess()
{
return "X";
}
}
You supply to the constructor of the Lazy<T> class a method that it can call when needed in order to create the object that it is wrapping. In the example above, I pass GoGetTheAnswerFromALongRunningProcess to its constructor.
Also note that it's usually a bad idea to have a property that can take a very long time to return. It's better to make it a method:
public static string GetString()
{
return _theAnswer.Value;
}
You are right in saying that the class can't be instantiated, but the class will exist within the application.
Therefore, only the first time the property is accessed, will the method GetStringFromSomeProcess be called. Every other time after that, the check for == null will resolve to false and the value evaluated by the first call will be returned.
Does it work correctly without creating an object of the GetStringFromSomeProces class? Since the string, theAnswer, is also static, it could potentially work, but I'm wondering when that variable will be initialized. Typically you would code it like you are suggesting with initialization of the GetStringFromSomeProcess Class.
Main.cs
...
GetStringFromSomeProcess getString = new GetStringFromSomeProcess();
string answer = getString.theAnswer();
...
GetStringFromSomeProcess.cs
public class GetStringFromSomeProcess
{
private string _theAnswer;
public string theAnswer
{
get
{
if(theAnswer == null)
{
GoGetTheAnswerFromALongRunningProcess getAnswer = new GoGetTheAnswerFromALongRunningProcess();
_theAnswer = getAnswer.GetAnswer();
}
return _theAnswer;
}
}
}

How do I avoid re-initializing a class that never changes?

I have a class that only needs to be initialized once in my code, but the function it is in is called multiple times and the class is initialized again and again. This class only needs to be called once because the data that is passed into it never changes and it is a waste to have my code reinitialize it more than once. I want to have a way for my code to check that this class has already been initialized and can grab the needed information that was already generated. My first thought was to design in the way of the Singleton Pattern, but I don't think that's necessary since this class is not needed anywhere else in my code. What is a simple way of doing something like this?
Make it static. Class will be initialized on first use...
A static class is one approach.
public static class MyClass
{
public static bool IsInited { get; private set; }
public static void Init(...)
{
...
IsInited = true;
}
}
If the Init has no arguments, e.g. can set all the properties itself, then you can use a static constructor instead of Init. Basically the constructor will be called the first time that other code accesses a property.
public static class MyClass
{
public static bool IsUnix { get; private set; }
static MyClass()
{
IsUnix = Environment.NewLine == '\n';
}

Static Initializer/Constructor Ordering

I ran into an interesting bug today, the code below would crash on the commented line on some machines, and not others. The problem appears to be related to ordering of static constructors, vs static initializers, and inheritance.
The fix was to move the code in the #region into another class, but I still don't understand what was actually happening, and why it seemed to only happen on some machines.
I have looked at these two articels:
http://csharpindepth.com/Articles/General/Singleton.aspx
http://csharpindepth.com/Articles/General/BeforeFieldInit.aspx
which shed some insight, but neither goes into how inheritance effects things.
public class CountAggregator : Aggregator
{
private static readonly CountAggregator _instance = new CountAggregator();
public static CountAggregator Instance
{
get
{
return _instance;
}
}
private CountAggregator() : base("CNT")
{
}
}
public class Aggregator
{
protected Aggregator(string id)
{
Id = id;
}
public string Id { get; private set; }
#region All Aggregators
private static readonly List<Aggregator> _allAggregators = new List<Aggregator>();
private static readonly Dictionary<string, Aggregator> _aggregatorsById = new Dictionary<string, Aggregator>();
public static IEnumerable<Aggregator> All
{
get { return _allAggregators; }
}
public static Aggregator GetAggregator(string id)
{
return _aggregatorsById[id];
}
static Aggregator()
{
_allAggregators.AddRange(new Aggregator[]
{
CountAggregator.Instance,
}
foreach (var aggregator in _allAggregators)
{
//this prints false, and the next line crashes
HtmlPage.Window.Alert((aggregator != null).ToString());
_aggregatorsById.Add(aggregator.Id, aggregator);
}
}
#endregion
}
Let's have class B, inheriting class A. The rule of thumb is that when the static constructor of class B is invoked, it first has make sure its ancestor, class A, was initialized before. However, when A's static constructor is initialized first, having a dependency on its ancestor B (which is weird anyway), B's static constructor cannot be executed before A's finishes, which results in any B's field to be in their default (=zero, null) state.
When you first access B anywhere in your code, then the sequence is as follows:
Access B
Invoke B's static constructor
Invoke A's static constructor, if necessary
initialize A's static fields
execute the constructor's code
initialize B's static fields
execute the constructor's code
On the other hand, when you first access A anywhere in your code, then the sequence is as follows:
Access A
Invoke A's static constructor
initialize A's static fields
execute the constructor's code, which includes
Access B and its static field B.Field
Invoke B's static constructor — circular dependency on A, cannot call
return B.Field which is uninitialized i.e. zero / null
use invalid value of B.Field
Your solution to pull out the code contained in the region is very logical and you should have done that anyway because of separation of concerns.

how to destroy a Static Class in C#

I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.
I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,
Additional question.
The idea of singleton is good, but I have the following questions:
If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.
I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late
thanks
pradeep
Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.
For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx
EDIT
The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.
Instead of a static class, have a static instance of a class:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
You can also delegate to an instance of the class:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.
EDIT: Additional question
When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.
Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.
You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, e.g. when you have to pass the object as a parameter.
Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (e.g., "using...").
The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
Building on Ahemd Said's answer: (and props to him!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(untested... but mostly right, I think)
You could also add in usage of the IDispose interface for more cleanup.
You can create a method in the static class which resets the values of all properties.
Consider you have a static class
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
Now you can use any of the below approaches from any other class to reset value of a static class
Approach 1 - Calling directly
ClassA.ResetValues();
Approach 2 - Invoking method dynamically from a known namespace and known class
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Approach 3 - Invoking method dynamically from an assembly/set of assemblies
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.
Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.
Eg I have a logger class as follows:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
In my constructor of my Form I call the following to setup the logger.
Logger.InitLogger(LogError);
Then from any class in my project I can do the following:
Logger.LogError("error",new Exception("error), true);

Categories