2010-07-23 44 views
12

soy normalmente aC# programador, pero ahora estoy trabajando en VB para éste proyecto cuando se utiliza para configurar una clase Singleton me gustaría seguir el modelo Jon Skeetpatrón singleton en VB

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

} 

o una de las variaciones ahora si escribo la declaración en C#

Singleton.Instance. ¿Qué procedimientos son todos los miembros que no son estáticos, b pero no a.

Ahora, cuando hacen lo mismo en 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 

consigo StackTracker.Instance.Instance y sigue adelante, mientras que no es el fin del mundo se ve mal.

Pregunta: ¿Hay alguna forma en VB para ocultar la segunda instancia para que el usuario no pueda invocar recursivamente Instancia?

Respuesta

4

Esta no es la propuesta de Jon. Ha implementado el third version referenced in the article on the matter, que señala que no funciona de acuerdo con la especificación EMCA debido a la falta de barreras de memoria.

Más bien, debe trabajar con la quinta versión, que utiliza una clase anidada y realiza la asignación de la instancia en la declaración del campo estático en la clase anidada.

Si está trabajando en .NET 4.0, entonces no tiene que hacer nada de esto. Puede crear un campo de solo lectura estático de tipo Lazy<T>, pasando LazyThreadSafetyMode.ExecutionAndPublication al constructor (junto con su Func<T> para indicar cómo crear la instancia) para garantizar que el valor solo se creará una vez.

A continuación, expone una propiedad que simplemente llama al Lazy<T>.Value property para devolver el valor de singleton con carga diferida.

+0

se parece mucho a la Segunda versión - seguridad de hilo simple, no usa 4.0 realmente utilizando 2.0 objetivo con IDE 2008. – Mike

11

Aquí está el código completo:

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 

Luego de usar esta clase, obtener la instancia usando:

Dim theSingleton As MySingleton = MySingleton.Instance 
+0

Gracias a [este artículo] (http://www.c-sharpcorner.com/blogs/6854/creating-lazyt-singleton-class.aspx) y [esta herramienta de conversión de C# a VB] (http://www.developerfusion.com/tools/convert/csharp-to-vb/). – rundavidrun

+0

Todavía se puede acceder a la propiedad MySingleton.Instance.Instance – Mike

3

La pregunta original no era acerca de cómo implementar el patrón Singleton, pero refiriéndose a el hecho de que en C# es un error de compilación intentar acceder a un miembro estático a través de una instancia. En el VB actual, es una advertencia.

Solución: Puede cambiar la configuración del compilador proyecto para "Tratar a todos los avisos como errores", pero no sé de ninguna manera de forma explícita el tratamiento de casi 42025 advertencia como un error.

Dicho esto, también hay un modo mucho más sencillo de implementar únicos en 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 

Esto se basa en VB flujos seguros sola inicialización de variables estáticas que es una característica que no se encuentra en C#. La línea de código que comienza con la palabra "estática" solo se evalúa una vez, incluso si se accede a la propiedad Instancia muchas veces desde muchos subprocesos.

+0

La referencia a su solución VB.Net también se publica [aquí] (https://www.codeproject.com/tips/390465/singleton-pattern-vb-net-using -static-variable) por Evgeniy Sukhikh – DrMarbuse