Давайте рассмотрим ваши заявления по одному:
Мой коллега сказал мне, что я никогда не должен использовать статические переменные, потому что если вы изменяете их в одном месте, они меняются везде.
Кажется довольно ясным, что ваш коллега имеет в виду основную особенность статических переменных: существует только один экземпляр статической переменной.Независимо от того, сколько экземпляров какого-либо класса вы создаете, любой доступ к статической переменной осуществляется к той же самой переменной .Для каждого экземпляра не существует отдельной переменной.
Он сказал мне, что вместо использования статических переменных я должен использовать Singleton.
Это нехорошо global совет.Статические переменные и синглтоны не конкурируют друг с другом и не заменяют друг друга.Singleton - это экземпляр класса, управляемый таким образом, что можно создать только один экземпляр.Статическая переменная аналогично привязана точно к одному (статическому) экземпляру класса, но может быть назначена не только экземпляром класса, но и любым типом данных, например скаляром.В действительности, чтобы эффективно использовать шаблон синглтона, вы должны сохранить его в статической переменной.Невозможно «использовать синглтон вместо статической переменной».
С другой стороны, возможно, он имел в виду что-то немного другое: возможно, он пытался сказать, что вместо вашего статического класса много разных статическихпеременные, метод, свойства и поля (вместе члены), которые функционируют так, как если бы они были классом, вы должны сделать эти поля нестатическими, а затем представить класс-оболочку как экземпляр Singleton.Вам все равно понадобится приватное статическое поле с методом или свойством (или, возможно, просто используйте свойство только для получения), чтобы раскрыть синглтон.
Я знаю, что синглтон предназначен дляограничение количества экземпляров одного класса одним.Как Singleton может помочь мне со статическими переменными?
Переменные статического класса и синглтон похожи в том, что они оба должны быть созданы один раз (первый реализуется компилятором, а второй - вашей реализацией).).Причина, по которой вы хотите использовать синглтон вместо статической переменной внутри класса, заключается в том, что ваш синглтон должен быть истинным экземпляром класса, а не состоять просто из собранных статических членовстатический класс.Этот синглтон затем назначается статической переменной, чтобы все вызывающие абоненты могли получить копию этого же экземпляра.Как я уже говорил выше, вы можете преобразовать все различные статические члены вашего статического класса в элементы экземпляра вашего нового нестатического класса, который вы будете представлять как синглтон.
Я также хотел бы отметить, чтодругие ответы, данные до сих пор, имеют проблемы с безопасностью потоков.Ниже приведены некоторые правильные шаблоны для управления Singletons.
Вы можете видеть, что экземпляр класса Singleton
, который имеет экземпляры (или не статические) члены, создается либо статической инициализацией, либо внутри статического конструктора.и присваивается переменной _singleton
.. Мы используем этот шаблон, чтобы гарантировать, что он будет создан только один раз .Затем статический метод Instance
предоставляет доступ только для чтения к переменной базового поля, которая содержит один и только один экземпляр Singleton
.
public class Singleton {
// static members
private static readonly Singleton _singleton = new Singleton();
public static Singleton Instance => _singleton
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
или точно такую же вещь, нос явным статическим конструктором:
public class Singleton {
// static members
private static readonly Singleton _singleton; // instead of here, you can...
static Singleton() {
_singleton = new Singleton(); // do it here
}
public static Singleton Instance => _singleton;
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
Вы также можете использовать свойство по умолчанию без явного вспомогательного поля (чтобы следовать), или в статическом конструкторе можно назначить свойство только для получения (не показано).
public class Singleton {
// static members
public static Singleton Instance { get; } = new Singleton();
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
Поскольку статические конструкторы гарантированно будут выполняться ровно один раз , будь то явные или неявные, то проблем с безопасностью потоков нет.Обратите внимание, что любой доступ к классу Singleton
может вызвать статическую инициализацию, даже доступ типа отражения.
Вы можете думать о статических членах класса почти как об отдельных, хотя и соединенных, класс:
Члены экземпляра (нестатические) функционируют как обычный класс.Они не живут, пока вы не выполните на них new Class()
.Каждый раз, когда вы делаете new
, вы получаете новый экземпляр.Члены экземпляра имеют доступ ко всем статическим членам, включая закрытые (в одном классе).
Статические члены похожи на элементы отдельного особого экземпляра класса, который вы не можете явно создатьиспользуя new
.Внутри этого класса только статические члены могут быть доступны или установлены.Существует неявный или явный статический конструктор, который .Net запускается во время первого доступа (так же, как экземпляр класса, только вы не создаете его явно, он создается при необходимости).Статические члены класса могут быть доступны любому другому классу в любое время, в экземпляре или вне его, но с учетом модификаторов доступа, таких как internal
или private
.