2010-06-28 26 views
7

Việc triển khai singleton này có chính xác và an toàn không?Cài đặt Singleton này có đúng và chỉ an toàn không?

class Class 
{ 
    public static readonly Class Instance; 

    static Class() 
    { 
     Instance = new Class(); 
    } 

    private Class() {} 
} 
+1

Sẽ không phải là nhà xây dựng hoàn toàn tái chế? –

+1

@Robert, không khai báo 'static Class()' là cho hàm dựng tĩnh mà chỉ được gọi một lần. Cuộc gọi đến 'new Class()' truy cập hàm tạo cá thể của lớp private(). –

+0

Lưu ý, có ctor cuộc gọi bên trong ctor tĩnh (class initializer). – Andreas

Trả lời

12

Về mặt kỹ thuật, phiên bản của bạn nên làm việc. Tuy nhiên, tôi sẽ không khuyên bạn nên để lộ một trường công khai trong lớp Singleton của bạn, và thích sử dụng một thuộc tính (chỉ với một getter). Điều này sẽ giúp chứng minh API của bạn trong tương lai nếu bạn cần thực hiện các thay đổi sau này. Tôi cũng khuyên bạn nên niêm phong bất kỳ thực hiện singleton, như subclassing một lớp singleton là hầu như luôn luôn là một ý tưởng tồi và có vấn đề.

tôi sẽ, cá nhân, sử dụng như sau trong C#, nếu bạn đang nhắm mục tiêu NET 3.5 hoặc sớm hơn:

public sealed class Singleton 
{ 
    static readonly Singleton instance = new Singleton(); 

    public static Singleton Instance 
    { 
     get 
     { 
      return instance; 
     } 
    } 

    static Singleton() { } 
    private Singleton() { } 
} 

Nếu bạn đang sử dụng .NET 4, bạn có thể làm cho điều này dễ dàng hơn cho chính mình qua Lazy<T>:

public sealed class Singleton 
{ 
    private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton()); 
    private Singleton() {} 
    public static Singleton Instance { get { return instance.Value; } } 
} 

phiên bản .NET 4 cũng có lợi thế là hoàn toàn lười biếng - ngay cả khi lớp Singleton bạn có phương pháp tĩnh khác được sử dụng trước khi truy cập của "Instance" bất động sản. Bạn cũng có thể làm một phiên bản .NET 3.5- hoàn toàn lười biếng, bằng cách sử dụng một lớp lồng nhau riêng. Jon Skeet demonstrated this on his blog.

+0

Tôi đặc biệt thích giải pháp Lazy . – Andreas

+0

@Andreas: Tôi cũng vậy - nó cũng "lười biếng" hơn - vì việc truy cập một phương thức tĩnh trên lớp sẽ không gây ra sự khởi tạo - chỉ có thuộc tính "Instance". –

+0

+1 cho 'Lazy ' –

2

Yes. Tôi cũng sẽ làm cho lớp 'sealed' để tránh bất kỳ sự nhầm lẫn nào trong tương lai.

1

Bạn nên làm như khởi tạo trong khai báo biến:

public static readonly Class Instance = new Class(); 
+1

Tại sao? ........... –

+0

Nó trì hoãn việc xây dựng Instance cho đến khi tham chiếu đầu tiên của nó, có thể tạo ra sự khác biệt. Thêm vào đó, tôi đọc sạch hơn. – Joe

+0

@Joe: Nó KHÔNG trì hoãn việc xây dựng cho đến khi tham chiếu đầu tiên. Trong thực tế, bạn phải để lại hàm tạo tĩnh tại chỗ hoặc lớp sẽ được đánh dấu beforefieldinit, điều này có thể thực sự khiến nó được khởi tạo ngay cả trước đó (mặc dù tôi thích sử dụng hàm tạo nội tuyến). –

Các vấn đề liên quan