синглтон в VB - PullRequest
       43

синглтон в VB

14 голосов
/ 23 июля 2010

Обычно я программист на c #, но сейчас я работаю в 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 illustrate the point
    public static void a()
    {
    }

    public void b()
    {
    }

} 

или один из вариантов сейчас, если я напишу утверждение в c #

Singleton.Instance Какими процедурами являются все элементы, которые не являются статичными, б, но не а.

Теперь, когда я делаю то же самое в 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 скрыть второй экземпляр, чтобы пользователь не мог рекурсивно вызвать Instance?

Ответы [ 4 ]

12 голосов
/ 17 октября 2012

Вот полный код:

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
5 голосов
/ 23 июля 2010

Это на самом деле не предложение, выдвинутое Джоном. Вы реализовали третью версию , упомянутую в статье по этому вопросу , которая, как он отмечает, не работает в соответствии со спецификацией EMCA из-за отсутствия барьеров памяти.

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

Если вы работаете в .NET 4.0, вам не нужно ничего этого делать. Вы можете создать статическое поле только для чтения типа Lazy<T>, передав LazyThreadSafetyMode.ExecutionAndPublication конструктору (вместе с Func<T>, чтобы указать, как создать экземпляр), чтобы гарантировать, что значение будет создано только один раз.

Затем вы выставляете свойство, которое просто вызывает Lazy<T>.Value property, чтобы возвратить загруженное ленивым одноэлементное значение.

3 голосов
/ 13 января 2017

Первоначальный вопрос был не о том, как реализовать шаблон синглтона, а о том, что в C # это ошибка компилятора при попытке получить доступ к статическому члену через экземпляр. В текущем 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, которая отсутствует в C #. Строка кода, начинающаяся со слова «static», оценивается только один раз, даже если свойство Instance доступно много раз из многих потоков.

0 голосов
/ 30 июня 2018

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

Class MySingleton

    'The instance initializes once and persists (provided it's not intentionally destroyed)
    Private Shared oInstance As MySingleton = New MySingleton

    'A property initialized via the Create method
    Public Shared Property SomeProperty() As Object = Nothing

   'Constructor cannot be called directly so prevents external instantiation
    Private Sub New()
        'Nothing to do
    End Sub

    'The property returns the single instance
    Public Shared ReadOnly Property Instance As MySingleton
        Get
            Return oInstance
        End Get
    End Property

    'The method returns the single instance while also initializing SomeProperty
    Public Shared Function Create(
        ByVal SomeParam As Object) As MySingleton

        _SomeProperty = SomeParam
        Return oInstance
    End Function
End Class

Очевидно, что вы обычно предоставляете либо свойство Instance или Create, но не оба (хотя вы могли бы, если захотите, по некоторым причинам).

В простейшем виде это:

Class MySingleton

    Private Shared oInstance As MySingleton = New MySingleton

    Private Sub New()
    End Sub

    Public Shared ReadOnly Property Instance As MySingleton
        Get
            Return oInstance
        End Get
    End Property
End Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...