Instrukcje deklaracji

Instrukcja deklaracji deklaruje nową zmienną lokalną, stałą lokalną lub lokalną zmienną referencyjną. Aby zadeklarować zmienną lokalną, określ jej typ i podaj jego nazwę. Można zadeklarować wiele zmiennych tego samego typu w jednej instrukcji, jak pokazano w poniższym przykładzie:

string greeting;
int a, b, c;
List<double> xs;

W instrukcji deklaracji można również zainicjować zmienną z jej wartością początkową:

string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();

Powyższe przykłady jawnie określają typ zmiennej. Kompilator może również wywnioskować typ zmiennej z wyrażenia inicjalizacji. W tym celu należy użyć var słowa kluczowego zamiast nazwy typu. Aby uzyskać więcej informacji, zobacz sekcję Niejawnie typizowane zmienne lokalne.

Aby zadeklarować stałą lokalną, użyj słowa kluczowego const, jak pokazano w poniższym przykładzie:

const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;

Podczas deklarowania stałej lokalnej należy ją również zainicjować.

Aby uzyskać informacje o lokalnych zmiennych referencyjnych, zobacz sekcję Zmienne referencyjne.

Niejawnie typizowane zmienne lokalne

Podczas deklarowania zmiennej lokalnej można umożliwić kompilatorowi wnioskowanie typu zmiennej z wyrażenia inicjalizacji. Aby to zrobić, użyj var słowa kluczowego zamiast nazwy typu:

var greeting = "Hello";
Console.WriteLine(greeting.GetType());  // output: System.String

var a = 32;
Console.WriteLine(a.GetType());  // output: System.Int32

var xs = new List<double>();
Console.WriteLine(xs.GetType());  // output: System.Collections.Generic.List`1[System.Double]

Jak pokazano w poprzednim przykładzie, niejawnie typizowane zmienne lokalne są silnie typizowane.

Uwaga

Jeśli używasz var w włączonym kontekście obsługującym wartość null, a typ wyrażenia inicjowania jest typem odwołania, kompilator zawsze wywnioskuje typ odwołania dopuszczalnego do wartości null, nawet jeśli typ wyrażenia inicjalizacji nie jest dopuszczalny do wartości null.

Typowym zastosowaniem var funkcji jest wyrażenie wywołania konstruktora. Użycie polecenia var pozwala nie powtarzać nazwy typu w deklaracji zmiennej i wystąpieniu obiektu, jak pokazano w poniższym przykładzie:

var xs = new List<int>();

Możesz użyć wyrażenia typu new docelowego jako alternatywy:

List<int> xs = new();
List<int>? ys = new();

Podczas pracy z typami anonimowymi należy używać niejawnie typicznie zmiennych lokalnych. W poniższym przykładzie pokazano wyrażenie zapytania, które używa typu anonimowego do przechowywania nazwy klienta i numeru telefonu:

var fromPhoenix = from cust in customers
                  where cust.City == "Phoenix"
                  select new { cust.Name, cust.Phone };

foreach (var customer in fromPhoenix)
{
    Console.WriteLine($"Name={customer.Name}, Phone={customer.Phone}");
}

W poprzednim przykładzie nie można jawnie określić typu zmiennej fromPhoenix . Typ ma IEnumerable<T> wartość , ale w tym przypadku T jest to typ anonimowy i nie można podać jego nazwy. Dlatego należy użyć polecenia var. Z tego samego powodu należy użyć var podczas deklarowania zmiennej customer iteracji w instrukcji foreach .

Aby uzyskać więcej informacji na temat niejawnie typiowanych zmiennych lokalnych, zobacz Niejawnie typizowane zmienne lokalne.

W dopasowywaniu var wzorca słowo kluczowe jest używane we var wzorcu.

Zmienne referencyjne

Podczas deklarowania zmiennej lokalnej i dodawania ref słowa kluczowego przed typem zmiennej należy zadeklarować zmienną referencyjną lub lokalnąref:

ref int aliasOfvariable = ref variable;

Zmienna referencyjna to zmienna, która odwołuje się do innej zmiennej, która jest nazywana odwołaniem. Oznacza to, że zmienna referencyjna jest aliasem do jego odwołania. Po przypisaniu wartości do zmiennej referencyjnej ta wartość jest przypisywana do odwołania. Podczas odczytywania wartości zmiennej referencyjnej zwracana jest wartość odwołania. W poniższym przykładzie pokazano, że zachowanie:

int a = 1;
ref int aliasOfa = ref a;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (1, 1)

a = 2;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (2, 2)

aliasOfa = 3;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (3, 3)

ref Użyj operatora= ref przypisania, aby zmienić odwołanie do zmiennej referencyjnej, jak pokazano w poniższym przykładzie:

void Display(int[] s) => Console.WriteLine(string.Join(" ", s));

int[] xs = [0, 0, 0];
Display(xs);

ref int element = ref xs[0];
element = 1;
Display(xs);

element = ref xs[^1];
element = 3;
Display(xs);
// Output:
// 0 0 0
// 1 0 0
// 1 0 3

W poprzednim przykładzie zmienna referencyjna element jest inicjowana jako alias pierwszego elementu tablicy. Następnie zostanie ref ponownie przydzielony, aby odwołać się do ostatniego elementu tablicy.

Możesz zdefiniować zmienną lokalną ref readonly . Nie można przypisać wartości do zmiennej ref readonly . ref Można jednak ponownie przypisać taką zmienną referencyjną, jak pokazano w poniższym przykładzie:

int[] xs = [1, 2, 3];

ref readonly int element = ref xs[0];
// element = 100;  error CS0131: The left-hand side of an assignment must be a variable, property or indexer
Console.WriteLine(element);  // output: 1

element = ref xs[^1];
Console.WriteLine(element);  // output: 3

Możesz przypisać odwołanie powrotne do zmiennej referencyjnej, jak pokazano w poniższym przykładzie:

using System;

public class NumberStore
{
    private readonly int[] numbers = [1, 30, 7, 1557, 381, 63, 1027, 2550, 511, 1023];

    public ref int GetReferenceToMax()
    {
        ref int max = ref numbers[0];
        for (int i = 1; i < numbers.Length; i++)
        {
            if (numbers[i] > max)
            {
                max = ref numbers[i];
            }
        }
        return ref max;
    }

    public override string ToString() => string.Join(" ", numbers);
}

public static class ReferenceReturnExample
{
    public static void Run()
    {
        var store = new NumberStore();
        Console.WriteLine($"Original sequence: {store.ToString()}");
        
        ref int max = ref store.GetReferenceToMax();
        max = 0;
        Console.WriteLine($"Updated sequence:  {store.ToString()}");
        // Output:
        // Original sequence: 1 30 7 1557 381 63 1027 2550 511 1023
        // Updated sequence:  1 30 7 1557 381 63 1027 0 511 1023
    }
}

W poprzednim przykładzie GetReferenceToMax metoda jest metodą returns-by-ref . Nie zwraca samej wartości maksymalnej, ale odwołanie zwraca alias do elementu tablicy, który przechowuje maksymalną wartość. Metoda Run przypisuje odwołanie powrotu do zmiennej referencyjnej max . Następnie, przypisując do maxprogramu , aktualizuje wewnętrzny magazyn store wystąpienia. Można również zdefiniować metodę ref readonly . Osoby wywołujące ref readonly metody nie mogą przypisać wartości do zwracania odwołania.

Zmienna iteracji instrukcji foreach może być zmienną referencyjną. Aby uzyskać więcej informacji, zobacz sekcję foreach instrukcji iteracji artykułu.

W scenariuszach o krytycznym znaczeniu dla wydajności użycie zmiennych referencyjnych i zwracanych może zwiększyć wydajność, unikając potencjalnie kosztownych operacji kopiowania.

Kompilator zapewnia, że zmienna referencyjna nie przeżyje odwołania i pozostaje prawidłowa przez cały okres istnienia. Aby uzyskać więcej informacji, zobacz sekcję Ref safe contexts (Konteksty bezpieczne ref) specyfikacji języka C#.

Aby uzyskać informacje o ref polach, zobacz sekcję refrefpól artykułu typy struktury.

zakres odwołania

Słowo kluczowe scoped kontekstowe ogranicza okres istnienia wartości. Modyfikator scoped ogranicza odpowiednio okres istnienia "ref-safe-to-escape" lub "bezpieczny do ucieczki" do bieżącej metody. W rzeczywistości dodanie scoped modyfikatora potwierdza, że kod nie przedłuży okresu istnienia zmiennej.

Można zastosować scoped do parametru lub zmiennej lokalnej. Modyfikator scoped może być stosowany do parametrów i ustawień lokalnych, gdy typ to ref struct. scoped W przeciwnym razie modyfikator może być stosowany tylko do lokalnych zmiennych referencyjnych. Obejmuje to zmienne lokalne zadeklarowane za pomocą ref modyfikatora i parametrów zadeklarowanych za pomocą inref modyfikatora lub out .

Modyfikator scoped jest niejawnie dodawany do this metod zadeklarowanych w structparametrach , out i parametrach, ref gdy typ to ref struct.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:

Aby uzyskać więcej informacji na temat modyfikatora, zobacz notatkę scoped o propozycji ulepszenia struktury niskiego poziomu.

Zobacz też