2010-07-23 38 views
12

Tôi thường aC# lập trình viên nhưng bây giờ đang làm việc trong VB cho một dự án này khi tôi sử dụng để thiết lập một lớp singleton tôi sẽ làm theo mô hình Jon SkeetSingleton pattern trong 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() 
    { 
    } 

} 

hoặc một trong các các biến thể ngay bây giờ nếu tôi viết tuyên bố trong C#

Singleton.Instance. Thủ tục là tất cả các thành viên không tĩnh, b nhưng không phải là a.

Bây giờ khi tôi làm như vậy trong 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 

tôi nhận được StackTracker.Instance.Instance và nó tiếp tục đi, trong khi nó không phải là sự kết thúc của thế giới có vẻ xấu.

Câu hỏi là có cách nào trong VB để ẩn dụ thứ hai để người dùng không thể đệ quy gọi Instance?

Trả lời

4

Đây thực sự không phải là đề xuất do Jon đưa ra. Bạn đã triển khai third version referenced in the article on the matter, mà ông chỉ ra không hoạt động theo thông số EMCA do thiếu rào cản bộ nhớ.

Thay vào đó, bạn nên làm việc với phiên bản thứ năm, sử dụng một lớp lồng nhau và thực hiện gán nhiệm vụ trong khai báo trường tĩnh trên lớp lồng nhau.

Nếu bạn đang làm việc trong .NET 4.0, thì bạn không phải thực hiện bất kỳ thao tác nào trong số này. Bạn có thể tạo trường chỉ đọc tĩnh loại Lazy<T>, chuyển LazyThreadSafetyMode.ExecutionAndPublication tới hàm tạo (cùng với Func<T> để chỉ ra cách tạo cá thể) để đảm bảo rằng giá trị sẽ chỉ được tạo một lần.

Sau đó, bạn hiển thị thuộc tính chỉ cần gọi số Lazy<T>.Value property để trả lại giá trị đơn được tải xuống lười biếng.

+0

có vẻ như phiên bản thứ hai - an toàn chủ đề đơn giản, không sử dụng 4.0 thực sự sử dụng mục tiêu 2.0 với IDE 2008. – Mike

11

Dưới đây là đoạn code đầy đủ:

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 

Sau đó, để sử dụng lớp này, có trường hợp sử dụng:

Dim theSingleton As MySingleton = MySingleton.Instance 
+0

Cảm ơn bạn đã đến [bài viết này] (http://www.c-sharpcorner.com/blogs/6854/creating-lazyt-singleton-class.aspx) và [công cụ chuyển đổi C# thành VB này] (http://www.developerfusion.com/tools/convert/csharp-to-vb/). – rundavidrun

+0

Vẫn có thể truy cập vào thuộc tính MySingleton.Instance.Instance – Mike

3

Câu hỏi ban đầu là không phải về làm thế nào để thực hiện mô hình singleton, nhưng đề cập đến thực tế là trong C# đó là một lỗi trình biên dịch để cố gắng truy cập một thành viên tĩnh thông qua một cá thể. Trong VB hiện tại nó là một cảnh báo.

Giải pháp: Bạn có thể thay đổi cài đặt trình biên dịch dự án "Hãy đối xử với tất cả các cảnh báo là lỗi", nhưng tôi không biết cách nào để chữa trị một cách rõ ràng chỉ cảnh báo 42.025 là một lỗi.

đó đang được nói, đó cũng là một cách đơn giản hơn nhiều để thực hiện độc thân trong 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 

này dựa vào VB thread-safe khởi duy nhất của biến tĩnh mà là một tính năng không tìm thấy trong C#. Dòng mã bắt đầu bằng từ "tĩnh" chỉ được đánh giá một lần ngay cả khi thuộc tính Instance được truy cập nhiều lần từ nhiều luồng.

+0

Tham chiếu đến giải pháp VB.Net của bạn cũng được đăng tại đây (https://www.codeproject.com/tips/390465/singleton-pattern-vb-net-using -static-variable) của Evgeniy Sukhikh – DrMarbuse