Udostępnij za pośrednictwem


Błąd kompilatora CS0236

Inicjator pola nie może odwoływać się do pola niestacjonanego, metody lub właściwości "name".

Pola instancji nie mogą być używane do inicjowania innych pól instancji w kontekście poza metodą.

Dlaczego ten błąd występuje

Kompilator wymusza to ograniczenie ze względu na sposób działania inicjowania obiektów w języku C#. Po utworzeniu obiektu inicjatory pól są przetwarzane przed uruchomieniem kodu konstruktora. W tej fazie:

  1. Ograniczenie zależności pól: podczas gdy inicjatory pól są przetwarzane w kolejności leksykalnej w jednym pliku, reguła uniemożliwia zależności między polami, aby umożliwić autorom klas zmienianie kolejności pól bez wprowadzania błędów kompilatora. W przypadku klas częściowych kolejność inicjatorów pól w różnych plikach źródłowych nie jest określona.

  2. Obiekt nie jest w pełni skonstruowany: po uruchomieniu inicjatorów pól wystąpienie obiektu jest w stanie niekompletnym. Zezwolenie na odwołania między polami w tej fazie może potencjalnie prowadzić do dostępu do niezainicjowanej pamięci lub nieprzewidywalnego zachowania.

  3. Bezpieczeństwo kompilatora: to ograniczenie zapobiega potencjalnym błędom środowiska uruchomieniowego i zapewnia przewidywalne zachowanie konstrukcji obiektu.

Kompilator wykrywa ten wzorzec podczas kompilacji i raportuje CS0236, aby zapobiec tym potencjalnym problemom.

Aby naprawić ten błąd

  1. Przenieś inicjalizację do konstruktora: wykonaj inicjalizację wewnątrz konstruktora obiektu, w którym wszystkie pola mają gwarancję dostępności.

  2. Użyj pól statycznych: jeśli pole, do których odwołuje się odwołanie, nie musi być specyficzne dla wystąpienia, rozważ utworzenie go statycznego.

  3. Użyj wartości domyślnych: zainicjuj pola za pomocą stałych wartości lub wyrażeń, które nie odwołują się do innych pól lub metod obiektu.

  4. Inicjowanie z opóźnieniem: użyj właściwości z polami zapasowymi dla złożonej logiki inicjowania, która zależy od innych elementów członkowskich wystąpienia.

Przykład

Poniższy przykład generuje plik CS0236 i pokazuje, jak go naprawić:

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;
    }
}

Dodatkowe przykłady

W poniższych przykładach przedstawiono różne scenariusze, w których występuje 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;
    }
}