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

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

Фон: То, что я пытаюсь выполнить, создает экземпляр API, и используйте этот экземпляр во всех моих классах (в противоположность устанавливанию новой связи, и т.д.).

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

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private Singleton()
     {
        APIClass api = new APIClass();  //Can this be done?
     }

     static Singleton() { Instance = new Singleton(); }
}

Как/Где Вы инстанцировали бы этого нового класса и как это нужно назвать от отдельного класса?

Править: Я понимаю, что Singleton-класс можно назвать с чем-то как

Singleton obj1 = Singleton.Instance();

но я смог бы получить доступ к методам в Классе API (т.е. obj1. Запустите)? (не, что я должен, просто спросив),

РЕДАКТИРОВАНИЕ № 2: Я, возможно, был немного преждевременен в проверке ответа, но у меня действительно есть одна мелочь, которая все еще вызывает меня проблемы. API запускается очень хорошо, к сожалению, я могу запустить два экземпляра?

Новый код

public sealed class SingletonAPI
{
 public static SingletonAPI Instance { get; private set; }

 private SingletonAPI() {}

 static SingletonAPI() { Instance = new SingletonAPI(); }     

 // API method:
 public void Start() { API myAPI = new API();}
 }

но если я пытаюсь сделать что-то вроде этого...

SingletonAPI api = SingletonAPI.Instance;
api.Start();
SingletonAPI api2 = SingletonAPI.Instance;  // This was just for testing.
api2.Start();

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

8
задан John Saunders 7 April 2010 в 04:10
поделиться

3 ответа

Почему бы просто не добавить общедоступное свойство APIClass к вашему синглтону?

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private APIClass _APIClass; 

     private Singleton()
     {
        _APIClass = new APIClass();  
     }

     public APIClass API { get { return _APIClass; } }

     static Singleton() { Instance = new Singleton(); }     
}

Тогда ваш вызывающий сайт будет выглядеть так:

Singleton.Instance.API.DoSomething();

Или, если вы являетесь автором класса API, вы могли бы сделать его самим синглтоном, а не обертывать это в синглтоне:

public sealed class SingletonAPI
{
     public static SingletonAPI Instance { get; private set; }

     private SingletonAPI() {}

     static SingletonAPI() { Instance = new SingletonAPI(); }     

     // API method:
     public void DoSomething() { Console.WriteLine("hi"); }
}

Вызов API:

SingletonAPI.Instance.DoSomething();
9
ответ дан 5 December 2019 в 10:02
поделиться

Вы бы не создали экземпляр класса - шаблон, который вы используете, в основном создает сам себя при первом использовании. Преимущество используемого вами метода заключается в том, что он потокобезопасен (будет создан только один раз, независимо от того, сколько потоков пытается получить к нему доступ), ленив (он не будет создаваться, пока вы не попытаетесь получить доступ к классу Singleton) и простой в реализации.

Все, что вам нужно сделать, чтобы использовать это, - это сделать:

 Singleton.Instance.MyMethodOnSingleton();

Или, как вариант:

 Singleton myInstance = Singleton.Instance; // Will always be the same instance...
 myInstance.DoSomething();
3
ответ дан 5 December 2019 в 10:02
поделиться

Вот официальный подход Microsoft .

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

Singleton.Instance.MyValue и Singleton.Instance.DoSomething ();

5
ответ дан 5 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: