Singleton pattern в vb
Я обычно программист на С#, но теперь я работаю в VB для этого одного проекта, когда я использую для создания одноэлементного класса. Я бы следовал модели Jon Skeet
public sealed class Singleton
{
static Singleton instance = null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
//Added to illistrate the point
public static void a()
{
}
public void b()
{
}
}
или один из вариантов теперь, если я напишу инструкцию в С#
Singleton.Instance. Какими процедурами являются все члены, которые не являются статическими, b, но не.
Теперь, когда я делаю то же самое в VB
Private Shared _instance As StackTracker
Private Shared ReadOnly _lock As Object = New Object()
Private Sub New()
_WorkingStack = New Stack(Of MethodObject)
_HistoryStack = New Queue(Of MethodObject)
End Sub
Public Shared ReadOnly Property Instance() As StackTracker
Get
SyncLock _lock
If (_instance Is Nothing) Then
_instance = New StackTracker()
End If
End SyncLock
Return _instance
End Get
End Property
Я получаю StackTracker.Instance.Instance, и он продолжает идти, а это не конец света, он выглядит плохо.
Вопрос: есть ли способ в VB скрыть второй экземпляр, чтобы пользователь не мог рекурсивно вызвать экземпляр?
Ответы
Ответ 1
Здесь полный код:
Public NotInheritable Class MySingleton
Private Shared ReadOnly _instance As New Lazy(Of MySingleton)(Function() New
MySingleton(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance() As MySingleton
Get
Return _instance.Value
End Get
End Property
End Class
Затем, чтобы использовать этот класс, получите экземпляр, используя:
Dim theSingleton As MySingleton = MySingleton.Instance
Ответ 2
На самом деле это не предложение Джона. Вы внедрили третью версию, указанную в статье по этому вопросу, которую он указывает, не работает в соответствии со спецификацией EMCA из-за отсутствия памяти.
Скорее, вы должны работать с пятой версией, которая использует вложенный класс и выполняет назначение экземпляра в объявлении статического поля в вложенном классе.
Если вы работаете в .NET 4.0, вам не нужно ничего делать. Вы можете создать статическое поле readonly типа Lazy<T>
, передав LazyThreadSafetyMode.ExecutionAndPublication
в конструктор (вместе с вашим Func<T>
, чтобы указать, как создать экземпляр), чтобы гарантировать, что значение будет создано только один раз.
Затем вы выставляете свойство, которое просто вызывает Lazy<T>.Value property
, чтобы вернуть ленивое загруженное одноэлементное значение.
Ответ 3
Исходный вопрос заключался не в том, как реализовать шаблон singleton, а в том, что в С# это ошибка компилятора, чтобы попытаться получить доступ к статическому члену через экземпляр. В текущем VB это предупреждение.
Решение:
Вы можете изменить настройки компилятора проекта на "Обработать все предупреждения как ошибки", но я не знаю, как явным образом рассматривать только предупреждение 42025 как ошибку.
Таким образом, существует гораздо более простой способ реализации одиночных чисел в VB:
public class Singleton
private sub new()
end sub
public shared readonly property Instance as Singleton
get
static INST as Singleton = new Singleton
return INST
end get
end property
end class
Это зависит от однопоточной инициализации статических переменных, зависящей от VB, которая является функцией, не найденной в С#. Строка кода, начинающаяся со слова "статический", оценивается только один раз, даже если свойство экземпляра обращается много раз от многих потоков.