Now I understand Singletone, I found several different implementations in the network, but I still don’t understand how they work. Singleton is a pattern that guarantees the presence of only one instance of a class, and in the examples I don’t understand a little how this “guarantee” is implemented. First example

public sealed class MySingleton { static MySingleton myInstance = null; MySingleton() { } public static MySingleton MyInstance { get { if (myInstance = = null) { myIinstance = new MySingleton(); } return myInstance; } private set; } } 

Second example:

 class Singleton { static Singleton obj; public static Singleton Obj { get { return obj; } } public string Data { get; set; } static Singleton() { obj = new Singleton(); } private Singleton() { Data = "I am a singleton"; } } //вызов { static void Main(string[] args) { Singleton s1 = Singleton.Obj; Console.WriteLine(s1.Data); } } 

Actually, can you explain how these two examples differ from each other, and how do they guarantee the presence of one instance of a class? Or are they both wrong, and is there a simpler and more understandable implementation of the pattern in c #?

  • 3
    And you try to create 2 copies of the code that you have. When that doesn't work, you should understand why this code is guaranteed by one copy. - ixSci
  • @ixSci, for the first option, by the way, it may turn out - Grundy
  • one
    @Grundy, well, if there are several streams, then a data race is obtained and two can be created, but as a result, only one will remain. - ixSci
  • "Is there a simpler and more understandable implementation of the pattern in c #?" - there is a public class Data { public static readonly Data Instance = new Data(); private Data() { } } public class Data { public static readonly Data Instance = new Data(); private Data() { } } - Stack

3 answers 3

The guarantee is implemented due to the fact that the class Singleton does not provide any other means of obtaining an instance, except for a static property - and the property is written so that it will never give up two different instances.

Pay attention to the private constructor - for singltons it is very important.

The difference between these examples is that the first option creates an instance on demand - the second creates its own instance when the class is initialized. Generally speaking, since the initialization of a class in .NET, in turn, also occurs on demand - the difference here is not very large.

Even if the differences in thread safety - for static designers, thread safety is guaranteed by the environment, but the first version of the singleton can only work in a single-threaded environment.

Regarding simple examples, I usually write singltons like this:

 public class Foo { private Foo() { } public static readonly Foo INSTANCE = new Foo(); // ... } 

In fact, this is the second option - but it looks much simpler. It just creates an immutable static variable, and nothing more.

PS

Current trends are to avoid singletons; should not make singletons everything. Before you make a single class a singleton, think: what’s terrible will happen if someone (perhaps you yourself) creates a second copy of this class? In most cases, the answer is "yes, nothing will happen." If so, do not make the class a singleton.

    Examples of singletons that are used in the .NET Framework
    can be viewed in the source. NET Framework

    Simple implementation of singleton:

     public class Data { public static readonly Data Instance = new Data(); private Data() { } } 

    If Data is a large object and needs to be created on demand, then you can use Lazy<T>

     public class Data { static readonly Data _Instance = new Lazy<Data>(() => new Data(), LazyThreadSafetyMode.PublicationOnly); public static Data Instance { get { return _Instance.Value; }} private Data() { } } 

      A simple implementation is using Lazy<T> . It is precisely with Lazy that we no longer have to think about all these multithreaded implementations, it works out of the box. Code from here :

       public sealed class Singleton { private static readonly Lazy<Singleton> instanceHolder = new Lazy<Singleton>(() => new Singleton()); private Singleton() { ... } public static Singleton Instance { get { return instanceHolder.Value; } } } 

      I usually use the program settings class for singleton. Well, that is They have a Save method and a bunch of fields that I need at runtime. If suddenly, when I want to add settings profiles, it’s enough to expand the Instance point, and not to rewrite absolutely all references to settings in the code, this is an advantage.

      The difference with the statics classes is small, but for example, for me in the static classes it is constantly hampered by the fact that it is usually very inconvenient to embroider them. Plus, storing two instances of class statics as two settings profiles is no longer possible. Whereas stupid instance serialization is quite a working solution.