次の方法で共有


コンパイラ エラー CS0236

フィールド初期化子は、非静的フィールド、メソッド、またはプロパティ 'name' を参照できません。

インスタンス フィールドを使用して、メソッドの外部にある他のインスタンス フィールドを初期化することはできません。

このエラーが発生する理由

コンパイラでは、C# でのオブジェクトの初期化のしくみにより、この制限が適用されます。 オブジェクトが作成されると、コンストラクター コードが実行される前にフィールド初期化子が処理されます。 このフェーズでは、次の操作を行います。

  1. フィールドの依存関係の制限: フィールド初期化子は 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;
    }
}