What is a singleton in C#?

2019-01-01 06:36发布

Pretty straight forward question.

What is a Singleton and when should I use it?

13条回答
与君花间醉酒
2楼-- · 2019-01-01 07:28

A singleton is a class which only allows one instance of itself to be created - and gives simple, easy access to said instance. The singleton premise is a pattern across software development.

There is a C# implementation "Implementing the Singleton Pattern in C#" covering most of what you need to know - including some good advice regarding thread safety.

To be honest, It's very rare that you need to implement a singleton - in my opinion it should be one of those things you should be aware of, even if it's not used too often.

查看更多
零度萤火
3楼-- · 2019-01-01 07:34

Singleton class is used to create a single instance for whole of the application domain.

public class Singleton
{
    private static Singleton singletonInstance = CreateSingleton();

    private Singleton()
    {
    }

    private static Singleton CreateSingleton()
    {
        if (singletonInstance == null)
        {
            singletonInstance = new Singleton();
        }

        return singletonInstance;
    }

    public static Singleton Instance
    {
        get { return singletonInstance; }            
    }
}

In this article it is described how we can create thread safe singleton class using readonly variable and their practical use in applications.

查看更多
春风洒进眼中
4楼-- · 2019-01-01 07:35

I use it for lookup data. Load once from DB.

public sealed class APILookup
    {
        private static readonly APILookup _instance = new APILookup();
        private Dictionary<string, int> _lookup;

        private APILookup()
        {
            try
            {
                _lookup = Utility.GetLookup();
            }
            catch { }
        }

        static APILookup()
        {            
        }

        public static APILookup Instance
        {
            get
            {
                return _instance;
            }
        }
        public Dictionary<string, int> GetLookup()
        {
            return _lookup;
        }

    }
查看更多
像晚风撩人
5楼-- · 2019-01-01 07:38

What it is: A class for which there is just one, persistent instance across the lifetime of an application. See Singleton Pattern.

When you should use it: As little as possible. Only when you are absolutely certain that you need it. I'm reluctant to say "never", but there is usually a better alternative, such as Dependency Injection or simply a static class.

查看更多
人气声优
6楼-- · 2019-01-01 07:41

You asked for C#. Trivial example:


public class Singleton
{
    private Singleton()
    {
        // Prevent outside instantiation
    }

    private static readonly Singleton _singleton = new Singleton();

    public static Singleton GetSingleton()
    {
        return _singleton;
    }
}
查看更多
萌妹纸的霸气范
7楼-- · 2019-01-01 07:42
using System;
using System.Collections.Generic;
class MainApp
{
    static void Main()
    {
        LoadBalancer oldbalancer = null;
        for (int i = 0; i < 15; i++)
        {
            LoadBalancer balancerNew = LoadBalancer.GetLoadBalancer();

            if (oldbalancer == balancerNew && oldbalancer != null)
            {
                Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server);
            }
            oldbalancer = balancerNew;
        }
        Console.ReadKey();
    }
}

class LoadBalancer
{
    private static LoadBalancer _instance;
    private List<string> _servers = new List<string>();
    private Random _random = new Random();

    private static object syncLock = new object();

    private LoadBalancer()
    {
        _servers.Add("ServerI");
        _servers.Add("ServerII");
        _servers.Add("ServerIII");
        _servers.Add("ServerIV");
        _servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
        if (_instance == null)
        {
            lock (syncLock)
            {
                if (_instance == null)
                {
                    _instance = new LoadBalancer();
                }
            }
        }

        return _instance;
    }

    public string Server
    {
        get
        {
            int r = _random.Next(_servers.Count);
            return _servers[r].ToString();
        }
    }
}

I took code from dofactory.com, nothing so fancy but I find this far good than examples with Foo and Bar additionally book from Judith Bishop on C# 3.0 Design Patterns has example about active application in mac dock.

If you look at code we are actually building new objects on for loop, so that creates new object but reuses instance as a result of which the oldbalancer and newbalancer has same instance, How? its due to static keyword used on function GetLoadBalancer(), despite of having different server value which is random list, static on GetLoadBalancer() belongs to the type itself rather than to a specific object.

Additionally there is double check locking here

if (_instance == null)
            {
                lock (syncLock)
                {
                    if (_instance == null)

since from MSDN

The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.

so every-time mutual-exclusion lock is issued, even if it don't need to which is unnecessary so we have null check.

Hopefully it helps in clearing more.

And please comment if I my understanding is directing wrong ways.

查看更多
登录 后发表回答