Я столкнулся с проблемой сегодня, и друг рекомендовал, чтобы я использовал глобальный статический экземпляр или более изящно шаблон "одиночка". Я провел несколько часов, читая об одиночных элементах, но несколько вещей все еще выходят из меня.
Фон: То, что я пытаюсь выполнить, создает экземпляр 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();
Я получаю ошибку при высказывании, что я не могу запустить больше чем один экземпляр.
Почему бы просто не добавить общедоступное свойство 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();
Вы бы не создали экземпляр класса - шаблон, который вы используете, в основном создает сам себя при первом использовании. Преимущество используемого вами метода заключается в том, что он потокобезопасен (будет создан только один раз, независимо от того, сколько потоков пытается получить к нему доступ), ленив (он не будет создаваться, пока вы не попытаетесь получить доступ к классу Singleton) и простой в реализации.
Все, что вам нужно сделать, чтобы использовать это, - это сделать:
Singleton.Instance.MyMethodOnSingleton();
Или, как вариант:
Singleton myInstance = Singleton.Instance; // Will always be the same instance...
myInstance.DoSomething();
Вот официальный подход Microsoft .
Прелесть синглтона заключается в том, что вы можете использовать его и получать к нему доступ в любом месте кода, не создавая экземпляра класса. Фактически это смысл существования одного экземпляра класса, например
Singleton.Instance.MyValue и Singleton.Instance.DoSomething ();