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 max
aktualizuje 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í in
modifiká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ě.