필드 이니셜라이저는 비정적 필드, 메서드 또는 속성 'name'을 참조할 수 없습니다.
인스턴스 필드는 메서드 외부에서 다른 인스턴스 필드를 초기화하는 데 사용할 수 없습니다.
이 오류가 발생하는 이유
컴파일러는 C#에서 개체 초기화가 작동하는 방식 때문에 이 제한을 적용합니다. 개체를 만들면 생성자 코드가 실행되기 전에 필드 이니셜라이저가 처리됩니다. 이 단계 중:
필드 종속성 제한: 필드 이니셜라이저는 단일 파일 내에서 어휘 순서로 처리되지만, 이 규칙은 클래스 작성자가 컴파일러 오류를 발생하지 않고 필드를 다시 정렬할 수 있도록 필드 간의 종속성을 방지합니다. 부분 클래스의 경우 여러 소스 파일에서 필드 이니셜라이저의 순서가 지정되지 않습니다.
개체가 완전히 생성되지 않음: 필드 이니셜라이저가 실행되면 개체 인스턴스가 불완전한 상태입니다. 이 단계 동안 필드 간에 참조를 허용하면 초기화되지 않은 메모리 또는 예측할 수 없는 동작에 액세스할 수 있습니다.
컴파일러 안전성: 이 제한은 잠재적인 런타임 오류를 방지하고 예측 가능한 개체 생성 동작을 보장합니다.
컴파일러는 컴파일 중에 이 패턴을 검색하고 CS0236을 보고하여 이러한 잠재적인 문제를 방지합니다.
이 오류를 해결하려면
초기화를 생성자로 이동: 모든 필드를 사용할 수 있도록 보장되는 인스턴스 생성자 내에서 초기화를 수행합니다.
정적 필드 사용: 참조된 필드가 인스턴스별로 지정될 필요가 없는 경우 정적 필드로 만드는 것이 좋습니다.
기본값 사용: 다른 인스턴스 멤버를 참조하지 않는 리터럴 값 또는 식을 사용하여 필드를 초기화합니다.
지연 초기화: 다른 인스턴스 멤버에 의존하는 복잡한 초기화 논리에 대한 백업 필드와 함께 속성을 사용합니다.
예시
다음 샘플에서는 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;
}
}
.NET