Home [C#] Const는 정적 멤버로 취급한다
Post
Cancel

[C#] Const는 정적 멤버로 취급한다

~최근에 다른 언어를 다루지 않아서 그렇게 느끼는 거일수도 있지만~ C#으로 업무를 하다 보면 간혹 “왜 안되지?”하는 부분들이 있다.

 C# Const가 그런 것 중 하나였는데 정리를 해두면 좋을 것 같아서 정리를 하였다.

문제를 인식하다

싱글톤 인스턴스를 통해 class 상수 멤버 변수에 접근하려고 했는데 접근이 되지 않았다.

문제 상황을 코드로 봐보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class SingleTon
{
    static SingleTon _instance = null;

    public static SingleTon Instance
    {
        get
        {
            return _instance ??= new SingleTon();
        }
    }
    private SingleTon() { }
    
    public const string _constData = "const Data";


}

static void Main(string[] args)
{
    Console.WriteLine(SingleTon.Instance._constData);
}

코드를 작성하면 컴파일 에러를 확인할 수 있다.

cs_12

원인

왜 그런가 검색을 해보았는데

원인은 C#에서 상수(==Const)는 정적 멤버로 취급하지만 정적 한정자(== static)을 선언을 허용하지 않기 때문이다.

해결 방법

해결 방법은 여러 가지 방법이 있다.

1. 정적 멤버처럼 사용하기

상수가 정적 멤버로 취급되기 때문에 기본적으로 정적 멤버와 동일하게 사용이 가능하다.

1
2
// 상수 _constData는 정적 멤버이다.
Console.WriteLine(SingleTon._constData);

2. Getter 사용하기

상수 데이터를 외부에 노출시키지 않고 싶을 때는 Getter 프로퍼티를 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SingleTon
{
    static SingleTon _instance = null;

    public static SingleTon Instance
    {
        get
        {
            return _instance ??= new SingleTon();
        }
    }

    private SingleTon() { }

    const string _constData = "const Data";

    // 상수 _constData에 대한 Getter Property 생성
    public string GetConstData => _constData;
}

static void Main(string[] args)
{
    Console.WriteLine(SingleTon.Instance.GetConstData);
}

3. readonly 키워드 사용하기

readonly는 정적 멤버로 취급하지 않기 때문에 싱글톤 인스턴스를 통해 접근할 수 있다.

C#에는 const와 동일한 기능을 하는 readonly 키워드가 존재한다.
readonly는 const와 다르게 선언에서 뿐만 아니라 생성자에서도 값을 수정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class SingleTon
{
    // 선언과 동시에 초기화 가능
    public readonly string _readonlyData = "readonly Data";
    
    /** 
     * 생성자에서도 초기화가 가능하다
     * 
     * 생성자에서 변수를 받아 readonly 멤버 변수에 값을 할당할 수 있는 것으로 보아 
     * readonly는 런타임 상수에 사용될 수 있음을 알 수 있다.
     */
    public SingleTon(string value) 
    {
        _readonlyData = value;
    }
    
    // "CS0191" 컴파일 에러!! -> 읽기 전용 필드에는 할당할 수 없습니다.
    public void SetData(string value)
    {
        _readonlyData = value;
    }
}

static void Main(string[] args)
{
    // 컴파일 에러가 발생하지 않음
    Console.WriteLine(SingleTon.Instance._readonlyData);
}

cs_13

This post is licensed under CC BY 4.0 by the author.