이니셜 라이저는 비 정적 필드, 메서드 또는 속성을 참조 할 수 없습니다.
클래스가 있고 다른 클래스에서 사용하면 같은 오류가 발생합니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace MySite
{
public class Reminders
{
public Dictionary<TimeSpan, string> TimeSpanText { get; set; }
// We are setting the default values using the Costructor
public Reminders()
{
TimeSpanText.Add(TimeSpan.Zero, "None");
TimeSpanText.Add(new TimeSpan(0, 0, 5, 0), "5 minutes before");
TimeSpanText.Add(new TimeSpan(0, 0, 15, 0), "15 minutes before");
TimeSpanText.Add(new TimeSpan(0, 0, 30, 0), "30 minutes before");
TimeSpanText.Add(new TimeSpan(0, 1, 0, 0), "1 hour before");
TimeSpanText.Add(new TimeSpan(0, 2, 0, 0), "2 hours before");
TimeSpanText.Add(new TimeSpan(1, 0, 0, 0), "1 day before");
TimeSpanText.Add(new TimeSpan(2, 0, 0, 0), "2 day before");
}
}
}
다른 클래스에서 클래스 사용
class SomeOtherClass
{
private Reminders reminder = new Reminders();
// error happens on this line:
private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
....
오류 (CS0236) :
A field initializer cannot reference the nonstatic field, method, or property
왜 발생하고 어떻게 해결합니까?
이 줄 :
private dynamic defaultReminder =
reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
인스턴스 변수를 사용하여 다른 인스턴스 변수 를 초기화 할 수 없습니다 . 왜? 컴파일러는이를 다시 정렬 할 수 있기 때문에 -은 없습니다 보장 reminder
전에 초기화됩니다 defaultReminder
위의 라인은, 그래서 수도 을 던져 NullReferenceException
.
대신 다음을 사용하십시오.
private dynamic defaultReminder = TimeSpan.FromMinutes(15);
또는 생성자에서 값을 설정하십시오.
private dynamic defaultReminder;
public Reminders()
{
defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}
이 컴파일러 오류에 대한 자세한 내용은 MSDN- 컴파일러 오류 CS0236에 있습니다.
해당 코드를 클래스 생성자에 넣어야합니다.
private Reminders reminder = new Reminders();
private dynamic defaultReminder;
public YourClass()
{
defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}
그 이유는 하나의 인스턴스 변수를 사용하여 필드 이니셜 라이저를 사용하여 다른 인스턴스 변수를 초기화 할 수 없기 때문입니다.
이렇게 사용할 수 있습니다
private dynamic defaultReminder => reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
is a field initializer and executes first (before any field without an initializer is set to its default value and before the invoked instance constructor is executed). Instance fields that have no initializer will only have a legal (default) value after all instance field initializers are completed. Due to the initialization order, instance constructors are executed last, which is why the instance is not created the moment the initializers are executed. Therefore the compiler cannot allow any instance property (or field) to be referenced before the class instance is fully constructed. This is because any access to an instance variable like reminder
implicitly references the instance (this
) to tell the compiler the concrete memory location of the instance to use.
이것은 this
인스턴스 필드 이니셜 라이저에서 허용되지 않는 이유이기도합니다 .
인스턴스 필드의 변수 이니셜 라이저는 생성중인 인스턴스를 참조 할 수 없습니다. 따라서 변수 이니셜 라이저가 simple_name을 통해 인스턴스 멤버를 참조하는 것은 컴파일 타임 오류이므로 변수 이니셜 라이저에서이를 참조하는 것은 컴파일 타임 오류입니다 .
인스턴스 필드 이니셜 라이저가 실행되기 전에 초기화가 보장되는 유일한 형식 멤버는 클래스 (정적) 필드 이니셜 라이저와 클래스 (정적) 생성자 및 클래스 메서드입니다. 정적 멤버는 인스턴스 독립적으로 참조되므로 언제든지 참조 할 수 있습니다.
class SomeOtherClass
{
private static Reminders reminder = new Reminders();
// This operation is allowed,
// since the compiler can guarantee that the referenced class member is already initialized
// when this instance field initializer executes
private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}
이것이 인스턴스 필드 이니셜 라이저가 클래스 멤버 (정적 멤버) 만 참조 할 수있는 이유입니다. 이 컴파일러 초기화 규칙은 결정적 유형 인스턴스화를 보장합니다.
자세한 내용은이 문서를 권장합니다 : Microsoft Docs : Class declarations .
즉, 다른 인스턴스 멤버를 참조하여 값을 초기화하는 인스턴스 필드는 인스턴스 생성자에서 초기화하거나 참조 된 멤버를 선언해야합니다 static
.
'ProgramingTip' 카테고리의 다른 글
나만의 방법에 대한 사용자 지정 완료 블록 (0) | 2020.10.15 |
---|---|
코드 골프 : Conway의 삶의 게임 (0) | 2020.10.15 |
Babel 6.x에서 기본 내보내기 값을 필요로합니다. (0) | 2020.10.14 |
무한 이미지를 찾기위한 알고리즘 (0) | 2020.10.14 |
Selenium RC로 Google 크롬을 실행하는 방법은 무엇입니까? (0) | 2020.10.14 |