views:

28

answers:

1

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 illistrate 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?

A: 

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.

casperOne
it looks a lot like the Second version - simple thread-safety, not using 4.0 actually using 2.0 target with 2008 IDE.
Mike