Avoiding Static Variables Using Singleton

One of my colleagues told me that I should never use static variables, because if you change them in one place, they change everywhere. He told me that instead of using static variables I should use Singleton. I know that Singleton is designed to limit the number of instances of one class to one. How can Singleton help me with static variables?

+4
source share
6 answers

One way to use a singleton (removed 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 cannot implement a singleton without using a static variable, and (I seem to remember - it was a while), this instance will be used for all queries. Because of this, it is inherently not protected by the flow.

Instead, think that these values ​​in the database or other persistent storage are more ceiling-friendly and create a class that interacts with this part 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 } } } 
+3
source

The whole point of the static modifier is that the object modified in this way is the same wherever it is used, since it does not require instantiation. The name originally came about, since the static variable has a fixed location in memory, and all objects related to it will refer to the same memory cell.

Now you can use the static field inside the class, in which case it exists before the class is created (built). There may be times when you want this.

Singleton is a different beast. This is a class that is limited to one instance using the private constructor and the static property. Therefore, in this regard, you still cannot escape statics using a singleton.

+3
source

Let me address your statements one at a time:

One of my colleagues told me that I should never use static variables, because if you change them in one place, they change everywhere.

It seems pretty obvious that your colleague means the core function 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 refers to the same variable. There is no 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 singletones do not compete with each other and do not actually replace each other. A singleton is an instance of a class, managed in such a way that only one instance can be created. A static variable is similarly associated with one (static) class instance, but can be assigned not only to the class instance, but also to any data type, for example, a scalar. In fact, in order to use a singleton pattern effectively, you have to store it in a static variable. It is impossible to "use a single element instead of a static variable".

On the other hand, perhaps he had something a little different in mind: perhaps he was trying to say that instead of your static class, which has many different static variables, methods, properties and fields (in general, members) that function as if they were a class, you have to make these fields non-static, and then set the wrapping class as an instance of Singleton. You still need a private static field with a method or property (or maybe just use the get-only property) to expose the singleton.

I know that Singleton is designed to limit the number of instances of one class to one. How can Singleton help me with static variables?

Static class variables and singleton are similar in that both of them must be instantiated once (the previous one was forced by the compiler, and the last according to your implementation). The reason you want to use singleton instead of a static variable inside a class is when your singleton should be a true instance of the class and not consist simply of assembled static members of a static class. This singleton is then assigned to a static variable so that all callers can get a copy of the same instance. As I said above, you can convert all the different static members of your static class into instance members of your new non-static class, which you open as a singleton.

I would also like to mention that in the other answers that have been given so far, everyone has thread safety issues. Below are some of the right templates for managing Singletons.

You can see that an instance of the Singleton class that has instances (or non-static) is created either by static initialization or inside a static constructor and assigned to the _singleton variable. We use this template to make sure it is created only once . Then, the static Instance method provides read-only access to the backup field variable that contains our one and only one Singleton instance.

 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 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 can also use the default property without an explicit support field (follow) or in the static constructor you 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 execute exactly once, whether implicit or explicit, then there are no thread safety issues . Note: any access to the Singleton class can trigger static initialization, even access to reflection.

You can think of the static members of a class as almost as a separate, albeit integrated, class:

  • Instance members (non-static) function like a regular class. They do not live until you execute new Class() on them. Every time you make new , you get a new instance. Instance members have access to all static members, including private members (in the same class).

  • Static elements are similar to members of a separate special instance of a class that cannot be explicitly created with new . Within this class, only static elements can be accessed or set. There is an implicit or explicit static constructor that .NET runs during the first access (just like an instance of a class, only you do not explicitly create it, it is created if necessary). Static class members can be accessed by any other class at any time, to or from an instance, albeit with access modifiers such as internal or private .

+2
source

To answer the question:

It is incredibly stupid (but possible) to create a singleton without a static field.

To do this, you need to use another static field, for example AppDomain.GetData or (in ASP.Net) HttpContext.Application .

+1
source

Just to answer your question (hopefully): instead of using a static class containing static elements such as Class1, you can implement the Singleton template as in Class2 (please do not start the 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 is also a (private) static field inside Class2 containing its instance.

Edit2 in response to user966638 comment: As far as I understand, you correctly understood that you have such code:

 public class Foo { private static Bar bar; } 

And your colleague suggests replacing it with this?

 public class Foo { private BarSingleton bar; } 

This may be the case if you want to have different instances of Foo, where each attribute of the instance panel can be set to zero, for example. But I'm not sure if he meant exactly what is used in this case.

0
source

Both single and static variables give you one instance of the class. Why do you prefer singleton over statics

  • With Singleton, you can control the lifetime of the instance yourself as you wish.
  • With Singleton, you have more control over instance initialization. This is useful when initializing an instance of a class; this is a tricky business.
  • It is difficult to make static variables thread safe, with singleton, this task will become very easy.

Hope this helps

-2
source

Source: https://habr.com/ru/post/1379159/


All Articles