2010-07-23 3 views
12

sono normalmente aC# programmatore, ma ora sto lavorando in VB per questo progetto quando ho utilizzato per impostare una classe Singleton avrei seguito il modello Jon Skeetpattern Singleton in 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 uno dei variazioni ora se scrivo la dichiarazione in C#

Singleton.Instance. Quali procedure sono tutti i membri che non sono statici, b ma non a.

Ora, quando faccio lo stesso 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 

ho StackTracker.Instance.Instance e continua ad andare, mentre non è la fine del mondo sembra male.

Domanda c'è un modo in VB per nascondere la seconda istanza in modo che l'utente non possa ricorsivamente chiamare Instance?

risposta

4

Questa non è in realtà la proposta di Jon. Hai implementato il third version referenced in the article on the matter, che egli sottolinea non funziona secondo le specifiche EMCA a causa della mancanza di barriere di memoria.

Piuttosto, dovresti lavorare con la quinta versione, che usa una classe nidificata ed esegue l'assegnazione dell'istanza nella dichiarazione del campo statico della classe nidificata.

Se si utilizza .NET 4.0, non è necessario eseguire alcuna operazione. È possibile creare un campo statico di tipo Lazy<T>, passando LazyThreadSafetyMode.ExecutionAndPublication al costruttore (insieme al proprio Func<T> per indicare come creare l'istanza) per garantire che il valore venga creato una sola volta.

Quindi, si espone una proprietà che chiama semplicemente Lazy<T>.Value property per restituire il valore di singleton con caricamento lento.

+0

sembra molto simile alla seconda versione: semplice thread-safety, non utilizza 4.0 effettivamente utilizzando la destinazione 2.0 con IDE 2008. – Mike

11

Ecco il codice 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 

quindi di utilizzare questa classe, ottenere l'istanza utilizzando:

Dim theSingleton As MySingleton = MySingleton.Instance 
+0

Grazie a [questo articolo] (http://www.c-sharpcorner.com/blogs/6854/creating-lazyt-singleton-class.aspx) e [questo strumento di conversione da C# a VB] (http://www.developerfusion.com/tools/convert/csharp-to-vb/). – rundavidrun

+0

È ancora possibile accedere alla proprietà MySingleton.Instance.Instance – Mike

3

La domanda iniziale non era su come implementare il pattern Singleton, ma riferendosi a il fatto che in C# è un errore del compilatore cercare di accedere a un membro statico tramite un'istanza. Nel VB corrente è un avvertimento.

Soluzione: È possibile modificare le impostazioni di progetto del compilatore per "Trattare tutti gli avvisi come errori", ma non so un modo per esplicitamente tratti proprio avvertimento 42025 come un errore.

Detto questo, v'è anche un modo molto più semplice da implementare single 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 

Questo si basa su VB thread-safe singola inizializzazione delle variabili statiche, che è una caratteristica non si trova in C#. La riga di codice che inizia con la parola "statico" viene valutata solo una volta, anche se si accede alla proprietà Instance molte volte da più thread.

+0

Anche il riferimento alla soluzione VB.Net è pubblicato [qui] (https://www.codeproject.com/tips/390465/singleton-pattern-vb-net-using -statica-variabile) di Evgeniy Sukhikh – DrMarbuse