public sealed class Singleton
{
Singleton() {}
public static Singleton Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested() {}
internal static readonly Singleton instance = new Singleton();
}
}
C #의 현재 응용 프로그램에서 Jon Skeet의 Singleton 패턴 을 구현 하고 싶습니다.
코드에 두 가지 의심이 있습니다.
-
중첩 클래스 내부의 외부 클래스에 액세스하는 방법은 무엇입니까? 내말은
internal static readonly Singleton instance = new Singleton();
폐쇄라고 불리는 것이 있습니까?
-
이 의견을 이해할 수 없습니다
// Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit
이 의견은 우리에게 무엇을 제안합니까?
답변
-
아니요, 클로저와 관련이 없습니다. 중첩 클래스는 여기에서 개인 생성자를 포함하여 외부 클래스의 개인 멤버에 액세스 할 수 있습니다.
-
beforefieldinit에 대한 기사를 읽으십시오 . no-op 정적 생성자를 원할 수도 있고 원하지 않을 수도 있습니다. 게으름이 필요한 것을 보장합니다. .NET 4 는 실제 유형 초기화 의미를 다소 변경 한다는 점을 명심해야합니다 (스펙 내에 있지만 이전보다 게으름).
당신이 할 정말 생각이 패턴을해야합니까? 당신은 도망 갈 수 없다고 확신합니까?
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance { get { return instance; } }
static Singleton() {}
private Singleton() {}
}
답변
질문 (1)과 관련하여 : Jon의 대답은 정확합니다. 왜냐하면 클래스를 공개 또는 내부적으로 만들지 않음으로써 암묵적으로 클래스 ‘Nested’를 비공개로 표시하기 때문입니다. ‘private’을 추가하여 명시 적으로 수행 할 수도 있습니다.
private class Nested
질문 (2)와 관련하여 : 기본적으로 beforeinitfield 및 유형 초기화 에 대한 게시물은 정적 생성자가 없으면 런타임에서 언제든지 초기화 할 수 있다는 것입니다 (그러나 사용하기 전에). 정적 생성자가있는 경우 정적 생성자의 코드가 필드를 초기화 할 수 있습니다. 즉, 유형을 요청할 때 런타임에서 필드를 초기화 할 수만 있습니다.
따라서 필드를 사용하기 전에 런타임에서 필드를 ‘사전 예방 적으로’초기화하지 않으려면 정적 생성자를 추가하십시오.
어느 쪽이든, 싱글 톤을 구현하는 경우 런타임에서 변수를 초기화해야한다고 생각하지 않을 때 가능한 한 게으른 초기화를 원하거나 신경 쓰지 않아도됩니다. 귀하의 질문에서 가능한 한 늦게 원한다고 가정합니다.
그것은 singleton 에 관한 Jon의 게시물을 만났습니다 .이 질문의 기본 주제는 IMO입니다. 아 그리고 의심 🙂
그가 ‘잘못된’으로 표시된 그의 싱글 톤 # 3이 실제로 정확하다는 것을 지적하고 싶습니다 (잠금은 자동으로 종료시 메모리 장벽을 암시 하기 때문에 ). 또한 인스턴스를 두 번 이상 사용할 때 싱글 톤 # 2보다 빠릅니다 (싱글 톤 :-)). 따라서 게으른 싱글 톤 구현이 실제로 필요한 경우 아마도 그 이유 중 하나 일 것입니다. 간단한 이유 때문에 (1) 진행중인 코드를 읽는 모든 사람에게 매우 분명합니다. 예외적으로.
궁금한 점이있는 경우 : 싱글 톤 # 6을 사용하지 않는 경우가 있습니다. 예외적으로 교착 상태와 예기치 않은 동작이 발생할 수 있기 때문입니다. 자세한 내용은 lazy의 잠금 모드 , 특히 ExecutionAndPublication을 참조하십시오 .