开发者

singleton pattern in vb

开发者 https://www.devze.com 2023-01-08 08:38 出处:网络
I am normally a c# programmer but am now working in VB for this one project when I use to set up a singleton class I would follow the Jon Skeet model

I am normally a c# programmer but am now working in VB for this one project when I use to set up a singleton class I would follow the Jon Skeet model

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()
    {
    }

} 

or one of the variations now if I write the statement in c#

Singleton.Instance What procedures is all of the members that are not static, b but not a.

Now when I do the same in 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

I get StackTracker.Instance.Instance and it keeps going, while it is not the end of the world it looks bad.

Question is there a way in VB to hide the second instance so the user can not recursively call Instance?


Here's the full code:

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

Then to use this class, get the instance using:

Dim theSingleton As MySingleton = MySingleton.Instance


The original question was not about how to implement the singleton pattern, but referring to the fact that in C# it's a compiler error to try to access a static member via an instance. In the current VB it's a warning.

Solution: You can change the project compiler settings to "Treat all warnings as errors", but I don't know any way to explicitly treat just warning 42025 as an error.

That being said, there is also a much simpler way to implement singletons in 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

This relies on VB thread-safe single initialization of static variables which is a feature not found in C#. The line of code beginning with the word "static" is only evaluated once even if the Instance property is accessed many times from many threads.


This is actually not the proposal put forth by Jon. You implemented the third version referenced in the article on the matter, which he points out doesn't work according to the EMCA spec due to lack of memory barriers.

Rather, you should work with the fifth version, which uses a nested class and performs the assignment of the instance in the declaration of the static field on the nested class.

If you are working in .NET 4.0, then you don't have to do any of this. You can create a static readonly field of type Lazy<T>, passing LazyThreadSafetyMode.ExecutionAndPublication to the constructor (along with your Func<T> to indicate how to create the instance) to guarantee that the value will only be created once.

Then, you expose a property which simply calls the Lazy<T>.Value property to return the lazy-loaded singleton value.


Maybe I'm missing something but I just do some variation on this, depending on what else is going on in the class:

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

Obviously, you would usually only provide either the Instance property or the Create method, not both (though you could if you wanted to for some reason).

In its simplest form it's:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消