Что такое синглтон в C #? - PullRequest
163 голосов
/ 28 января 2010

Довольно простой вопрос.

Что такое синглтон и когда мне его использовать?

Ответы [ 14 ]

131 голосов
/ 28 января 2010

Синглтон - это класс, который позволяет создавать только один его экземпляр и обеспечивает простой и легкий доступ к нему. Одиночная предпосылка - образец всей разработки программного обеспечения.

Существует реализация C # "Реализация шаблона Singleton в C #" , охватывающая большую часть того, что вам нужно знать, включая некоторые полезные советы относительно безопасности потоков .

Если честно, очень редко вам нужно реализовать синглтон - по моему мнению, это должна быть одна из тех вещей, о которых вы должны знать, даже если она не используется слишком часто.

50 голосов
/ 28 января 2010

Вы просили C #. Тривиальный пример:


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

    private static readonly Singleton _singleton = new Singleton();

    public static Singleton GetSingleton()
    {
        return _singleton;
    }
}
39 голосов
/ 28 января 2010

Что это такое: Класс, для которого существует только один постоянный экземпляр на протяжении всего жизненного цикла приложения. См. Шаблон синглтона .

Когда вы должны его использовать: Как можно меньше. Только когда вы абсолютно уверены , что вам это нужно. Я не хочу говорить «никогда», но обычно есть лучшая альтернатива, такая как инъекция зависимости или просто статический класс.

24 голосов
/ 16 декабря 2011

другой способ реализации синглтона в c #, я лично предпочитаю этот способ, потому что вы можете получить доступ к экземпляру класса singeton как свойство, а не как метод.

public class Singleton
    {
        private static Singleton instance;

        private Singleton() { }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                    instance = new Singleton();
                return instance;
            }
        }

        //instance methods
    }

но, насколько я знаю, оба способа считаются "правильными", поэтому это просто личное дело.

10 голосов
/ 19 апреля 2015
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();
        }
    }
}

Я взял код с dofactory.com , ничего особенного, но Я считаю, что это гораздо лучше, чем примеры с Foo и Bar дополнительно книга от Джудит Бишоп на C # 3.0 DesignВ шаблонах есть пример активного приложения в доке Mac.

Если вы посмотрите на код, мы фактически строим новые объекты в цикле для , так что создается новый объект, но повторно используется экземпляр, в результате чегоу oldbalancer и newbalancer есть один и тот же экземпляр, как?это происходит из-за статического ключевого слова, используемого в функции GetLoadBalancer () , несмотря на то, что сервер имеет другое значение, которое является случайным списком, статическое в GetLoadBalancer () относится к типусам по себе, а не к конкретному объекту.

Кроме того, здесь двойная проверка блокировки здесь

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

с MSDN

Ключевое слово lock гарантирует, что один поток не входит в критический раздел кода, в то время как другой поток находится в критическом разделе.Если другой поток попытается ввести заблокированный код, он будет ожидать блокировки до тех пор, пока объект не будет освобожден.

, поэтому каждый раз выдается блокировка взаимного исключения, даже если он не 'нам не нужно ничего лишнего, поэтому у нас есть нулевая проверка.

Надеюсь, это поможет очистить больше.

И, пожалуйста, прокомментируйте, если я понимаю, что неверно.

6 голосов
/ 28 января 2010

Синглтон (и это не связано с C #, это шаблон проектирования ОО) - это когда вы хотите, чтобы в вашем приложении создавался только ОДИН экземпляр класса. Использование обычно включает в себя глобальные ресурсы, хотя я скажу из личного опыта, они очень часто являются источником большой боли.

5 голосов
/ 28 января 2010

Хотя может существовать только один экземпляр синглтона, он не совпадает со статическим классом. Статический класс может содержать только статические методы и никогда не может быть создан, тогда как экземпляр синглтона может использоваться так же, как и любой другой объект.

2 голосов
/ 20 декабря 2015

Что такое синглтон:
Это класс, который позволяет создавать только один его экземпляр и обычно предоставляет простой доступ к этому экземпляру.

Когда следует использовать:
Это зависит от ситуации.

Примечание: пожалуйста, не используйте соединение с БД, для подробного ответа см. к ответу @Chad Grant

Вот простой пример Singleton:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

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

Вы также можете использовать Lazy<T> для создания Singleton.

Смотрите здесь для более подробного примера, используя Lazy<T>

2 голосов
/ 11 мая 2015

Я использую его для поиска данных. Загрузите один раз из БД.

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;
        }

    }
2 голосов
/ 28 января 2010

Это шаблон проектирования, и он не специфичен для c #. Подробнее об этом в Интернете и ТАК, как в этой статье Википедии .

В разработке программного обеспечения, синглтон шаблон это шаблон дизайна, который используется для ограничения реализации класс для одного объекта. Это полезно когда ровно один объект нужен для координировать действия по всей системе. Концепция иногда обобщается к системам, которые работают больше эффективно, когда только один объект существует или ограничивает инстанцирование на определенное количество объекты (скажем, пять). Некоторые считают это анти-паттерн, судя, что это чрезмерно используется, вводит ненужные ограничения в ситуациях, когда единственный экземпляр класса на самом деле не требуется, и вводит глобальное состояние в приложение.

Вам следует использовать его, если вы хотите создать класс, экземпляр которого можно создать только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...