2010-06-28 3 views
7

이 싱글 톤 구현은 정확하고 스레드로부터 안전한가요? 이 작업을 수행하는 방법의이 싱글 톤 구현은 정확하고 스레드로부터 안전한가요?

class Class 
{ 
    public static readonly Class Instance; 

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

    private Class() {} 
} 
+1

생성자가 무한 반복 되나요? –

+1

@Robert 아니,'static Class()'선언은 한 번만 호출되는 정적 생성자를위한 선언입니다. 'new Class()'를 호출하면 'Private Class()'인스턴스 생성자에 도달합니다. –

+0

정적 ctor (클래스 이니셜 라이저)에는 인스턴스 ctor 호출이 있습니다. – Andreas

답변

12

기술적으로, 당신의 버전이 작동합니다. 그러나 Singleton 클래스 내에서 공용 필드를 공개하는 것은 좋지 않으며 Property (getter 만 사용)를 사용하는 것을 선호합니다. 나중에 변경해야하는 경우 API를 미래 보장하는 데 도움이됩니다. 싱글 톤 클래스를 서브 클래 싱하는 것은 거의 항상 나쁜 생각이고 문제이기 때문에 어떤 싱글 톤 구현도 씰링하는 것이 좋습니다. 당신이 .NET 4를 사용하는 경우

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

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

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

, 당신은 자신이 더 쉽게 만들 수 있습니다 : 당신이 .NET 3.5 또는 이전 버전을 표적으로하는 경우

나는, 개인적으로는 C#으로 다음을 사용합니다 Lazy<T>를 통해 : - 귀하의 Singleton 클래스는 이전의 "인스턴스"속성의 ​​액세스에 사용되는 다른 정적 방법이있는 경우에도

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; } } 
} 

닷넷 4 버전은 완전히 게으른되는 장점이 있습니다. 전용, 중첩 된 클래스를 사용하여 완전히 지연된 .NET 3.5 버전을 수행 할 수도 있습니다. Jon Skeet demonstrated this on his blog.

+0

나는 특히 게으른 솔루션을 좋아한다. – Andreas

+0

@ Andreas : 저도 - 클래스의 정적 메서드에 액세스해도 인스턴스화가 발생하지 않으므로 "인스턴스"속성 만 사용하므로 더 "게으른"것입니다. –

+0

+1'Lazy ' –

2

예. 나는 또한 미래의 혼란을 피하기 위해 클래스 'sealed'을 만들 것입니다.

1

당신은 변수 선언에서 초기화를 수행해야합니다

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

이유 ... ... –

+0

인스턴스의 생성이 첫 번째 참조까지 지연되어 차이가 발생할 수 있습니다. 플러스 나에게 그것은 깨끗한 읽기. – Joe

+0

@ Joe : 첫 번째 참조가 될 때까지 공사가 지연되지 않습니다. 사실, 정적 생성자를 그대로 두거나 클래스가 beforefieldinit로 표시되어 실제로 인스턴스화 될 수도 있습니다 (인라인 생성자를 사용하는 것이 더 좋음). –

관련 문제