본문 바로가기
책/Effective C#

Effective C# - Item13 정적 클래스 멤버를 올바르게 초기화하라

by 코딩하는 돼징 2023. 12. 1.
반응형

정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화 해야한다. 

C#에서는 정적 멤버 초기화 구문과 정적 생성자라는 두 가지 기능을 제공한다.

예시

static MyClass()는 정적 생성자이며 클래스가 처음으로 사용될 때 한 번만 호출된다. 이를 통해 정적 멤버 변수 myPiggy를 초기화 할 수 있다. 

public class MyClass
{
    // 정적 멤버 변수
    public static int myPiggy;

    // 정적 멤버 초기화 구문
    static MyClass()
    {
        myPiggy = 42;
    }
}

 


정적 생성자를 사용하는 대표적 사례 : 싱글톤 패턴

인스턴스가 하나만 생성되도록 보장하는 디자인 패턴 중 하나이다. 정적 생성자를 사용하여 구현할 때 정적 멤버 변수를 초기화하고 유일한 인스턴스를 생성한다.

01 정적 멤버를 간단히 초기화 하는 경우

theOneAndOnly 정적 멤버 변수는 클래스가 처음으로 사용될 때 한 번만 초기화되고 유지된다.

public class MySingleton
{
    // 1. 정적 멤버 변수 선언 및 초기화
    private static readonly MySingleton theOneAndOnly = new Singleton();
    
    // 2. 정적 프로퍼티
    public static MySingleton TheOnly{get{ return theOneAndOnly; }}
    
    // Private 생성자
    private MySingleton()
    {
        // 외부에서 직접 인스턴스 생성 방지
    }
}

02 정적 생성자 버전 

정적 생성자를 활용하여 초기화 과정을 더 복잡하게 처리할 수 있다. 정적 생성자는 클래스가 처음으로 사용될 때 호출되며 해당 호출 이전에 정적 멤버 변수인 theOneAndOnly를 초기화 시킨다. 이러한 방식으로 복잡한 초기화 로직이나 여러 단계를 거치는 작업을 수행할 수 있다.

public class MySingleton2
{
    // 1. 정적 멤버 변수 선언
    private static readonly MySingleton2 theOneAndOnly;
    
    // 2. 정적 생성자
    static MySingleton2()
    {
        // 정적 멤버 변수 초기화
        theOneAndOnly = new MySingleton2();
    }
    
    // 정적 프로퍼티
    // TheOnly가 호출될때 theOneAndOnly가 반환된다.
    public static MySingleton2 TheOnly{ get{return theOneAndOnly;}}
    
    // Private 생성자
    private MySingleton2()
    {
        // 외부에서 직접 인스턴스 생성 방지
    }
}

인스턴스 멤버 초기화 구문과 마찬가지로 정적 멤버 초기화 구문 또한 정적 생성자가 호출되기 이전에 실행되며 베이스 클래스의 정적 생성자보다 먼저 호출된다.


03 반드시 정적 생성자를 사용해야 하는 경우 : 예외가 발생할 가능성이 있는 경우

멤버 초기화 구문 대신 반드시 정적 생성자를 사용해야 할 때도 있다. 바로 예외가 발생할 가능성이 있는 경우인데, 멤버 초기화 구문의 경우 예외를 잡아낼 방법이 없기 떄문이다. 정적 생성자를 이용하면 다음과 같이 코드를 작성할 수 있다.

static MySingleton2()
{
    try
    {
        theOneAndOnly = new MySingleton2();
    }
    catach
    {
        // 복구를 시도한다.
    }
}

결론

정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화 해야한다. 

 

 

본 게시글은 Effective C#을 읽고 정리하였습니다.

 

반응형

댓글