Chyba kompilátoru CS0236

Inicializátor pole nemůže odkazovat na nestatické pole, metodu nebo vlastnost 'name'.

Pole instance nelze použít k inicializaci jiných polí instance mimo metodu.

Proč k této chybě dochází

Kompilátor toto omezení vynucuje kvůli tomu, jak funguje inicializace objektů v jazyce C#. Při vytvoření objektu se inicializátory polí zpracovávají před spuštěním jakéhokoli konstruktoru kódu. Během této fáze:

  1. Omezení závislostí polí: Zatímco inicializátory polí se zpracovávají v lexikálním pořadí v rámci jednoho souboru, pravidlo zabraňuje závislostem mezi poli, aby autoři tříd mohli měnit uspořádání polí bez zavedení chyb kompilátoru. U částečných tříd není zadáno pořadí inicializátorů polí v různých zdrojových souborech.

  2. Objekt není plně sestaven: Při spuštění inicializátorů polí je instance objektu v neúplném stavu. Povolení odkazů mezi poli v této fázi by mohlo vést k přístupu k neinicializované paměti nebo nepředvídatelnému chování.

  3. Bezpečnost kompilátoru: Toto omezení zabraňuje potenciálním chybám za běhu a zajišťuje předvídatelné chování při vytváření objektů.

Kompilátor zjistí tento vzor během kompilace a hlásí CS0236, aby se zabránilo těmto potenciálním problémům.

Oprava této chyby

  1. Přesunutí inicializace do konstruktoru: Proveďte inicializaci uvnitř konstruktoru instance, kde jsou zaručena dostupnost všech polí.

  2. Používejte statická pole: Pokud odkazované pole nemusí být specifické pro instanci, zvažte jeho statické nastavení.

  3. Použijte výchozí hodnoty: Inicializace polí s literálními hodnotami nebo výrazy, které neodkazují na jiné členy instance.

  4. Opožděná inicializace: Pro logiku komplexní inicializace, která závisí na jiných členech instance, použijte vlastnosti s backingovými poli.

  5. Primární konstruktor: K inicializaci veřejného pole s hodnotou pole instance nebo hodnoty zadané jako argument konstruktoru použijte primární konstruktory .

Příklad

Následující ukázka vygeneruje CS0236 a ukazuje, jak ji opravit:

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 lze také opravit pomocí primárního konstruktoru , jak je znázorněno v následujícím příkladu:

public class MyClass
{
    public int i = 5;
    public int j => i;
}

// or
public class MyClass(int i)
{
    public int j => i;
}

Další příklady

Následující příklady ukazují různé scénáře, ve kterých dochází k 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;
    }
}