다음을 통해 공유


컴파일러 오류 CS0236

필드 이니셜라이저는 비정적 필드, 메서드 또는 속성 'name'을 참조할 수 없습니다.

인스턴스 필드는 메서드 외부에서 다른 인스턴스 필드를 초기화하는 데 사용할 수 없습니다.

이 오류가 발생하는 이유

컴파일러는 C#에서 개체 초기화가 작동하는 방식 때문에 이 제한을 적용합니다. 개체를 만들면 생성자 코드가 실행되기 전에 필드 이니셜라이저가 처리됩니다. 이 단계 중:

  1. 필드 종속성 제한: 필드 이니셜라이저는 단일 파일 내에서 어휘 순서로 처리되지만, 이 규칙은 클래스 작성자가 컴파일러 오류를 발생하지 않고 필드를 다시 정렬할 수 있도록 필드 간의 종속성을 방지합니다. 부분 클래스의 경우 여러 소스 파일에서 필드 이니셜라이저의 순서가 지정되지 않습니다.

  2. 개체가 완전히 생성되지 않음: 필드 이니셜라이저가 실행되면 개체 인스턴스가 불완전한 상태입니다. 이 단계 동안 필드 간에 참조를 허용하면 초기화되지 않은 메모리 또는 예측할 수 없는 동작에 액세스할 수 있습니다.

  3. 컴파일러 안전성: 이 제한은 잠재적인 런타임 오류를 방지하고 예측 가능한 개체 생성 동작을 보장합니다.

컴파일러는 컴파일 중에 이 패턴을 검색하고 CS0236을 보고하여 이러한 잠재적인 문제를 방지합니다.

이 오류를 해결하려면

  1. 초기화를 생성자로 이동: 모든 필드를 사용할 수 있도록 보장되는 인스턴스 생성자 내에서 초기화를 수행합니다.

  2. 정적 필드 사용: 참조된 필드가 인스턴스별로 지정될 필요가 없는 경우 정적 필드로 만드는 것이 좋습니다.

  3. 기본값 사용: 다른 인스턴스 멤버를 참조하지 않는 리터럴 값 또는 식을 사용하여 필드를 초기화합니다.

  4. 지연 초기화: 다른 인스턴스 멤버에 의존하는 복잡한 초기화 논리에 대한 백업 필드와 함께 속성을 사용합니다.

예시

다음 샘플에서는 CS0236을 생성하고 이를 해결하는 방법을 보여 줍니다.

public class MyClass
{
    public int i = 5;

    // CS0236: Field initializer cannot reference instance field 'i'
    // This restriction allows class authors to rearrange fields without compiler errors
    public int j = i;  // CS0236

    public MyClass()
    {
        // This works because both fields are guaranteed to be initialized
        // before constructor code runs
        j = i;
    }
}

추가 예시

다음 예제에서는 CS0236이 발생하는 다양한 시나리오를 보여 줍니다.

public class Examples
{
    private string name = "Default";
    
    // CS0236: Cannot reference instance field in initializer
    private string displayName = name.ToUpper();
    
    // CS0236: Cannot reference instance method in initializer  
    private int length = GetNameLength();
    
    // CS0236: Cannot reference instance property in initializer
    private string formatted = FormattedName;
    
    public string FormattedName => $"Name: {name}";
    
    private int GetNameLength() => name.Length;
    
    public Examples()
    {
        // All of these work in the constructor:
        displayName = name.ToUpper();
        length = GetNameLength();
        formatted = FormattedName;
    }
}