Příkazy deklarace

Příkaz deklarace deklaruje novou místní proměnnou, místní konstantu nebo místní referenční proměnnou. Pokud chcete deklarovat místní proměnnou, zadejte její typ a zadejte jeho název. V jednom příkazu můžete deklarovat více proměnných stejného typu, jak ukazuje následující příklad:

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

V příkazu deklarace můžete také inicializovat proměnnou s počáteční hodnotou:

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

Předchozí příklady explicitně určují typ proměnné. Kompilátor také může odvodit typ proměnné z inicializačního výrazu. Uděláte to tak, že místo názvu typu použijete var klíčové slovo. Další informace najdete v části Implicitně napsané místní proměnné .

Pokud chcete deklarovat místní konstantu const , použijte klíčové slovo, jak ukazuje následující příklad:

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

Když deklarujete místní konstantu, musíte ji také inicializovat.

Informace o místních referenčních proměnných najdete v části Referenční proměnné .

Implicitně zadané místní proměnné

Když deklarujete místní proměnnou, můžete kompilátoru nechat odvodit typ proměnné z inicializačního výrazu. Uděláte to tak, že místo názvu typu použijete var klíčové slovo:

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 ukazuje předchozí příklad, implicitně typované místní proměnné jsou silného typu.

Poznámka:

Při použití var v povoleném kontextu s podporou null a typ inicializačního výrazu je odkazový typ, kompilátor vždy odvodí typ odkazu s možnou hodnotou null, i když typ inicializačního výrazu není nullable.

Běžné použití var je s konstruktorem vyvoláním výrazu. Použití var umožňuje neopakovat název typu v deklaraci proměnné a instanci objektu, jak ukazuje následující příklad:

var xs = new List<int>();

Výraz typu new cíle můžete použít jako alternativu:

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

Při práci s anonymními typy je nutné použít implicitně napsané místní proměnné. Následující příklad ukazuje výraz dotazu, který používá anonymní typ k uložení jména a telefonního čísla zákazníka:

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

V předchozím příkladu nemůžete explicitně zadat typ fromPhoenix proměnné. Typ je, ale v tomto případě T je IEnumerable<T> anonymním typem a nemůžete zadat jeho název. Proto potřebujete použít var. Z stejného důvodu je nutné použít var při deklaraci customer proměnné iterace v foreach příkazu.

Další informace o implicitně zadaných místních proměnných najdete v tématu Implicitně typované místní proměnné.

V porovnávání vzorů var se klíčové slovo používá ve vzoruvar.

Referenční proměnné

Když deklarujete místní proměnnou a před typ proměnné přidáte ref klíčové slovo, deklarujete referenční proměnnou ref nebo místní:

ref int aliasOfvariable = ref variable;

Referenční proměnná je proměnná, která odkazuje na jinou proměnnou, která se nazývá odkaz. To znamená, že odkazová proměnná je alias pro jeho odkaz. Když přiřadíte hodnotu referenční proměnné, tato hodnota je přiřazena odkazující proměnné. Při čtení hodnoty referenční proměnné se vrátí hodnota referentu. Následující příklad ukazuje toto chování:

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)

Pomocí operátoru ref = ref přiřazení změňte odkaz na proměnnou odkazu, jak ukazuje následující příklad:

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

V předchozím příkladu element je referenční proměnná inicializována jako alias prvního prvku pole. Potom se ref znovu přiřazuje, aby odkazoval na poslední prvek pole.

Můžete definovat místní proměnnou ref readonly . Nemůžete přiřadit hodnotu proměnné ref readonly . Můžete ref ale změnit přiřazení takové referenční proměnné, jak ukazuje následující příklad:

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

Můžete přiřadit návrat odkazu k referenční proměnné, jak ukazuje následující příklad:

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

V předchozím příkladu GetReferenceToMax je metoda returns-by-ref metoda. Nevrací samotnou maximální hodnotu, ale odkaz vrátí alias prvku pole, který obsahuje maximální hodnotu. Metoda Run přiřadí odkaz návratu k max referenční proměnné. Potom přiřazením maxaktualizuje interní úložiště store instance. Můžete také definovat metodu ref readonly . Volající metody nemůžou ref readonly přiřadit hodnotu k vrácení odkazu.

Iterační proměnnou foreach příkazu může být referenční proměnná. Další informace najdete v foreach části příkazu článku o příkazech iterace.

V kritických scénářích s výkonem může použití referenčních proměnných a návratů zvýšit výkon tím, že se zabrání potenciálně nákladným operacím kopírování.

Kompilátor zajišťuje, aby referenční proměnná neobsáhla svůj odkaz a zůstala platná po celou dobu jeho života. Další informace najdete v části Referenční bezpečné kontexty specifikace jazyka C#.

Informace o ref polích najdete vref části pole v článku o typech ref struktur.

ref s vymezeným oborem

Kontextové klíčové slovo scoped omezuje životnost hodnoty. scoped Modifikátor omezuje životnost ref-safe-to-escape nebo safe-to-escape na aktuální metodu. Přidáním modifikátoru scoped se v podstatě ověří, že váš kód neprodlouží životnost proměnné.

Můžete použít scoped u parametru nebo místní proměnné. scoped Modifikátor lze použít na parametry a místní hodnoty, pokud je typ .ref struct scoped V opačném případě lze modifikátor použít pouze na místní referenční proměnné. To zahrnuje místní proměnné deklarované modifikátorem ref a parametry deklarovanými pomocí inmodifikátorů nebo ref out modifikátorů.

scoped Modifikátor je implicitně přidán do this metod deklarovaných v parametrech struct, out a ref parametry, pokud je typ .ref struct

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Další informace o modifikátoru scoped naleznete v návrhu vylepšení struktury nízké úrovně.

Viz také