Do I need to mark public method as static if I want to initialize private variable only once or it is enough for making "singleton property" in the following code?
public IEqualityComparer<T> GetComparer<T>()
{
if (typeof (IUserShift).IsAssignableFrom(typeof (T)))
return UserShiftComparer.Value as IEqualityComparer<T>;
throw new ArgumentOutOfRangeException("There is no avaliable comparer for the type!", nameof(T));
}
private static readonly Lazy<UserShiftTrackingComparer> UserShiftComparer = new Lazy<UserShiftTrackingComparer>();
If you make your field static then only one copy will exist and in this case since you have it within Lazy, it will only be created when it is accessed. If it is never accessed, it will never be created.
Making your method static means it is not tied to an instance of the class but the class itself. All instance methods can access static methods and static fields and instance fields and instance methods. On the other hand, static methods can only access static fields and other static methods.
To answer your question, you DO NOT need to make the method static to initialize the UserShiftComparer only once.
Related
I am wondering why my static constructor is outputting default constructor Static Constructor, and not the other way around Static Constructor and Default constructor or just Default constructor. When I use a static constructor, it should execute the static constructor first. However, from the code below,
The First question: why is the default constructor is called before the static constructor?
class Program
{
static void Main(string[] args)
{
var test = Single.S;
}
class Single{
static readonly Single s = new Single();
public static Single S{
get { return s; }
}
private Single(){
Console.WriteLine("Default");
}
static Single(){
Console.WriteLine("staic");
}
}
}
The Second question: How come the Static Single constructor is being called as well?
Depending on Microsoft
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.
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
baseline = DateTime.Now.Ticks;
}
}
In this case, the static constructor will be called before the default constructor
but in this line,
static readonly Single s = new Single();
you are using "static field initialization"
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 exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor.
in this case, static field initialization will be completed before the constructor is called,
then the static constructor is run before your default constructor,
but when it runs, it's using new Single(), so passing through your non-static constructor path.
This causes to call the default constructor before the static constructor.
Finally, you can try this and you will see it will execute
the static constructor before the default constructor
private class Single
{
private static readonly Single s;
static Single()
{
Console.WriteLine("static");
s = new Single();
}
}
References
C# and beforefieldinit
When is a static constructor called in C#?
How does static field initialization work in C#?
Static constructor called after instance constructor?
Static constructor can run after the non-static constructor. Is this a compiler bug?
The first thing that happens here when loading the class is
static Single s = new Single();
C# executes static initializers like this in the order they are seen. I am not sure if this ordering point also applies to the static constructor but from your test it seems that the static initializer does occur before the static constructor.
In any case, in order to assign to static Single s, one must first construct new Single(), which means invoking the non-static constructor. I am not sure what you would get if you read from Single.s in the non-static constructor but I would expect either null or an exception.
I am having a lot of trouble choosing between using Singleton or Static for a class that contains state variables. I wanted the class object to instantiate and exist only as one.
I know both ways can store state variables. Static Class seems easy to deal with the variables as all methods will become static, which they can access the static variables without any further work.
However, this case is different for a Singleton. I have both kinds of methods; A kind that needs to access to the Singleton's Instance variable, and other that without any access to the Instance variable, which I can mark it static.
An Example:
/// <summary>Singleton.</summary>
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton(); /// <summary>Instance.</summary>
public static Singleton Instance { get { return instance; } }
private int integer; /// <summary>Integer.</summary>
public int Integer { set { integer = value; } get { return integer; } }
/// <summary>Constructor.</summary>
private Singleton() { }
/// <summary>TestA</summary>
public void TestA(int val)
{
Integer = val;
}
/// <summary>TestB</summary>
public static int TestB(int val)
{
return Instance.Integer * val;
}
/// <summary>TestC</summary>
public static int TestC(int val)
{
return val * val;
}
}
From the example given above, there are three methods; TestA, TestB, and TestC.
TestA is a non-static instance method that has access to its property.
TestB is a static method, but accesses the Instance to get its properties.
TestC is a static method that the instance has no use.
This begs the question:
Should the Singleton contains only static methods, and access to its Instance properties and methods by going through the static Instance property? In other words, all methods are similar to TestB or TestC.
Should the Singleton contains only non-static methods, regardless whether if it needs the Instance or not? All methods similar to TestA.
Should the Singleton contains both mixed static and non-static (in this case, TestA, and TestB kind) methods? Which I believe it can get rather messy.
If not, what should I do? Should I dump the idea of Singleton, and go with all static for every classes that is to be instantiated only once?
Edit: With similar question, should Singleton even contain any Static variables/field/properties beside the Instance?
You shouldnt mix up both patterns.
If you have an Singleton pattern the only static field should be the Instance(+ the getter). All your methods and fields should be accessible through the instance. If you mix it up it will only cause confusion.
If you choose the the static class pattern don't use a secret instance inside thats the job of .NET.
If you are not sure what pattern fits best for you, have a look into this Singleton-vs-Static article. It explains the pro's and con's of both of them: https://www.dotnetperls.com/singleton-static
A colleague of mine told me that I should never use static variables because if you change them in one place, they are changed everywhere. He told me that instead of using static variables I should use Singleton.
I know that Singleton is for limitation of the number of instances of one class to one.
How can Singleton help me with static variables?
Let's address your statements one at a time:
A colleague of mine told me that I should never use static variables because if you change them in one place, they are changed everywhere.
It seems fairly clear that your colleague means the basic feature of static variables: there is only one instance of a static variable. No matter how many instances of any class you create, any access to a static variable is to the same variable. There is not a separate variable for each instance.
He told me that instead of using static variables I should use Singleton.
This is not good global advice. Static variables and singletons aren't in competition with each other and aren't really substitutes for each other. A singleton is an instance of a class, managed in such a way that only one instance is possible to create. A static variable is similarly tied to exactly one (static) instance of a class, but could be assigned with not only a class instance but any data type such as a scalar. In actuality, to effectively use the singleton pattern, you must store it in a static variable. There is no way to "use a singleton instead of a static variable".
On the other hand, perhaps he meant something slightly different: perhaps he was trying to say that instead of your static class having many different static variables, methods, properties, and fields (altogether, members) that function as if they were a class, you should make those fields non-static, and then expose the wrapping class as a Singleton instance. You would still need a private static field with a method or property (or perhaps just use a get-only property) to expose the singleton.
I know that Singleton is for limitation of the number of instances of one class to one. How can Singleton help me with static variables?
A static class's variables and a singleton are alike in that they both are instantiated once (the former enforced by the compiler and the latter enforced by your implementation). The reason you'd want to use a singleton instead of a static variable inside of a class is when your singleton needs to be a true instance of a class, and not consist simply of the collected static members of a static class. This singleton then gets assigned to a static variable so that all callers can acquire a copy of that same instance. As I said above, you can convert all the different static members of your static class to be instance members of your new non-static class which you will expose as a singleton.
I would also like to mention that the other answers given so far all have issues around thread safety. Below are some correct patterns for managing Singletons.
Below, you can see that an instance of the Singleton class, which has instance (or non-static) members, is created either by static initialization or within the static constructor, and is assigned to the variable _singleton.. We use this pattern to ensure that it is instantiated only once. Then, the static method Instance provides read-only access to the backing field variable, which contains our one, and only one, instance of Singleton.
public class Singleton {
// static members
private static readonly Singleton _singleton = new Singleton();
public static Singleton Instance => _singleton
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
or, the exact same thing but with an explicit static constructor:
public class Singleton {
// static members
private static readonly Singleton _singleton; // instead of here, you can...
static Singleton() {
_singleton = new Singleton(); // do it here
}
public static Singleton Instance => _singleton;
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
You could also use a property default without an explicit backing field (below) or in a static constructor can assign the get-only property (not shown).
public class Singleton {
// static members
public static Singleton Instance { get; } = new Singleton();
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
Since static constructors are guaranteed to run exactly once, whether implicit or explicit, then there are no thread safety issues. Note that any access to the Singleton class can trigger static initialization, even reflection-type access.
You can think of static members of a class as almost like a separate, though conjoined, class:
Instance (non-static) members function like a normal class. They don't live until you perform new Class() on them. Each time you do new, you get a new instance. Instance members have access to all static members, including private members (in the same class).
Static members are like members of a separate, special instance of the class that you cannot explicitly create using new. Inside this class, only static members can be accessed or set. There is an implicit or explicit static constructor which .Net runs at the time of first access (just like the class instance, only you don't explicitly create it, it's created when needed). Static members of a class can be accessed by any other class at any time, in or out of an instance, though respecting access modifiers such as internal or private.
EDIT #ErikE's response is the correct approach.
For thread safety, the field should be initialized thusly:
private static readonly Singleton instance = new Singleton();
One way to use a singleton (lifted from http://msdn.microsoft.com/en-us/library/ff650316.aspx)
using System;
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
/// non-static members
public string Foo { get; set; }
}
Then,
var foo = Singleton.Instance.Foo;
Singleton.Instance.Foo = "Potential thread collision here.";
Note that the instance member is a static field. You can't implement a singleton without using a static variable, and (I seem to recall - it's been awhile) this instance will be shared across all requests. Because of that, it's inherently not thread safe.
Instead, consider putting these values in a database or other persistent store that's more thread-friendly, and creating a class that interfaces with that portion of your database to provide transparent access.
public static class Foo
{
public static string Bar
{
get { /// retrieve Bar from the db }
set { /// update Bar in the db }
}
}
The whole point of the static modifier is to ensure that the object thus modified is the same wherever it is used as it requires no instantiation. The name originally came about as a static variable has a fixed location in memory and all items referring to it will reference the same memory location.
Now you may wish to use a static field within a class, in which case it exists before the class is instantiated (constructed). There may be instances where you would want this.
A singleton is a different beast. It is a class that is limited to a single instantiation by use of a private constructor and a static property. So in that regard you still can't avoid statics by using a singleton.
To answer the stated question:
It is incredibly stupid (but possible) to create a singleton without a static field.
To do it, you need to use someone else's static field, such as AppDomain.GetData or (in ASP.Net) HttpContext.Application.
Just to answer your question (I hope): Instead of using a static class containing static members like Class1 you can implement the Singleton pattern like in Class2 (please don't begin a discussion about lazy initialization at this point):
public static class Class1
{
public static void DoSomething ()
{
}
}
public static class Class2
{
private Class2() {
}
private Class2 instance;
public Class2 GetInstance(){
if (instance == null)
instance = new Class2();
return instance;
}
public void DoSomething ()
{
}
}
Instead of calling Class1.DoSomething() you can use Class2.GetInstance().DoSomething().
Edit: As you can see there's still a (private) static field inside Class2 holding it's instance.
Edit2 in answer to user966638's comment:
Do I understand you correct that you have code like this:
public class Foo {
private static Bar bar;
}
And your collegue suggests to replace it by this?
public class Foo {
private BarSingleton bar;
}
This could be the case if you want to have different Foo instances where each instance's bar attribute could be set to null for example. But I'm not sure if he meant this what exactly is the use case he is talking about.
Both singleton and static variables give you one instance of a class. Why you should prefer singleton over static is
With Singleton you can manage the lifetime of the instance yourself, they way you want
With Singleton, you have greater control over the initialization of the instance. This useful when initializing an instance of a class is complicated affair.
It's challenging to make static variables thread-safe, with singleton, that task becomes very easy
Hope this helps
public class MyClass<T>
{
public static readonly String MyStringValue;
static MyClass()
{
MyStringValue = GenerateString();
}
private static String GenerateString()
{
//Dynamically generated ONCE per type (hence, not const)
}
public void Foo()
{
Console.WriteLine(MyStringValue);
}
}
It's my understanding that the static readonly String won't get generated until the static constructor is called on the class. But, the static constructor won't be called until one of the static methods or variables is accessed.
In a multi-threaded environment is it possible to run into issues because of this? Basically, is the static constructor by default singleton locked or do I have to do this myself? That is... do I have to do the following:
private static Object MyLock;
static MyClass()
{
lock(MyLock)
{
if (MyStringValue == null)
MyStringValue = GenerateString();
}
}
The static constructor is guaranteed to run only once per instantiated type. So you don't need your locking.
Note that it will run once for each generic parameter. And the static fields on the generic class aren't shared between different generic parameters either.
To avoid this why not make the value a static property with only a get accessor which returned the cached value, which you could then make private? Accessing the property get would assure the static constructor ran first.
Can I call(access) non static method from static method ??
Like I have static method If yes, how??
public static void method() //like this is a static method
{
methodsec(); //from here I want to access non static method defined below
}
public void methodsec() // non static method
{
}
Yes, but you need a reference to do it through:
public static void StaticMethod()
{
someInstance.InstanceMethod();
}
public void InstanceMethod()
{
}
You need to think about which instance you want to call the method on. Instance methods typically use the state of the instance, so the method is likely to do different things depending on which instance it's called on.
No you can't call it exactly like that. You either need an instance of the class to call the non-static method, or it also needs to be static.
An alternative approach would be to use a singleton pattern - so you only have one instance of the class available throughout your code, and don't need to use static methods. That way, all methods in the class can call each other. It's hard to tell whether this would actually suit your needs, without further info but could be the way to go