Deklarációs utasítások
A deklarációs utasítás új helyi változót, helyi állandót vagy helyi referenciaváltozót deklarál. Helyi változó deklarálásához adja meg a típusát, és adja meg a nevét. Egy utasításban több azonos típusú változót is deklarálhat, ahogy az alábbi példa mutatja:
string greeting;
int a, b, c;
List<double> xs;
Egy deklarációs utasításban inicializálhat egy változót a kezdeti értékével:
string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();
Az előző példák kifejezetten meghatározzák a változó típusát. Azt is lehetővé teheti, hogy a fordító az inicializálási kifejezésből következtetsen egy változó típusára. Ehhez használja a var
kulcsszót egy típus neve helyett. További információkért tekintse meg az Implicitly típusú helyi változók szakaszt .
Helyi állandó deklarálásához használja a const
kulcsszót az alábbi példában látható módon:
const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;
Helyi állandó deklarálásakor inicializálnia kell azt is.
A helyi referenciaváltozókkal kapcsolatos információkért tekintse meg a Referenciaváltozók szakaszt .
Implicit típusú helyi változók
Helyi változó deklarálásakor a fordító az inicializálási kifejezésből következtethet a változó típusára. Ehhez használja a var
kulcsszót egy típus neve helyett:
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]
Ahogy az előző példa is mutatja, az implicit módon beírt helyi változók erősen be vannak állítva.
Feljegyzés
Ha az engedélyezett null értékű környezetben használjavar
, és az inicializálási kifejezés típusa hivatkozástípus, a fordító mindig null értékű hivatkozástípust következtet, még akkor is, ha az inicializálási kifejezés típusa nem null értékű.
A konstruktorok meghívásának kifejezése var
gyakran használatos. A használatával var
nem ismételhet meg típusnevet változódeklarációban és objektum-példányosításban, ahogy az alábbi példa is mutatja:
var xs = new List<int>();
Másik lehetőségként cél típusú new
kifejezést is használhat:
List<int> xs = new();
List<int>? ys = new();
Névtelen típusok használata esetén implicit típusú helyi változókat kell használnia. Az alábbi példa egy olyan lekérdezési kifejezést mutat be, amely névtelen típussal tárolja az ügyfél nevét és telefonszámát:
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}");
}
Az előző példában nem adhatja meg explicit módon a fromPhoenix
változó típusát. A típus az, IEnumerable<T> de ebben az esetben T
egy névtelen típus, és nem adhatja meg a nevét. Ezért kell használnia var
. Ugyanezért az utasításban az iterációs változó deklarálásakor customer
kell használnia.var
foreach
Az implicit típusú helyi változókkal kapcsolatos további információkért lásd az implicit típusú helyi változókat.
A mintamegfeleltetésben a var
kulcsszót a rendszer egy var
mintában használja.
Referenciaváltozók
Ha deklarál egy helyi változót, és hozzáadja a ref
kulcsszót a változó típusa előtt, deklarál egy referenciaváltozót vagy egy ref
helyit:
ref int aliasOfvariable = ref variable;
A referenciaváltozó egy másik változóra hivatkozó változó, amelyet hivatkozónak nevezünk. Vagyis a referenciaváltozó a hivatkozási aliasa. Amikor egy értéket egy referenciaváltozóhoz rendel, a rendszer ezt az értéket rendeli hozzá a hivatkozáshoz. Amikor beolvassa egy referenciaváltozó értékét, a hivatkozás értéke lesz visszaadva. Az alábbi példa ezt a viselkedést mutatja be:
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)
A hozzárendelési ref
operátorral = ref
módosíthatja egy referenciaváltozó hivatkozását, ahogy az az alábbi példában is látható:
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
Az előző példában a element
referenciaváltozó az első tömbelem aliasaként van inicializálva. Ezután újra hozzárendeli ref
, hogy az utolsó tömbelemre hivatkozzon.
Megadhat egy helyi változót ref readonly
. Nem rendelhet hozzá értéket egy ref readonly
változóhoz. Egy ilyen referenciaváltozót azonban újra hozzárendelhet ref
, ahogy az alábbi példa is mutatja:
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
Hivatkozási visszatérést rendelhet egy referenciaváltozóhoz, ahogyan az az alábbi példában is látható:
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
}
}
Az előző példában a GetReferenceToMax
metódus egy visszatérési ref metódus. Nem magát a maximális értéket adja vissza, hanem egy olyan hivatkozást, amely a maximális értéket tartalmazó tömbelem aliasa. A Run
metódus hivatkozási visszatérést rendel a max
referenciaváltozóhoz. Ezután a hozzárendeléssel max
frissíti a példány belső tárolóját store
. Metódust ref readonly
is definiálhat. A metódus hívói ref readonly
nem rendelhetnek értéket a referencia-visszatéréshez.
Az utasítás iterációs változója foreach
lehet referenciaváltozó. További információkért tekintse meg az foreach
Iteration utasításokkal foglalkozó cikk utasítás szakaszát.
A teljesítmény szempontjából kritikus helyzetekben a referenciaváltozók és a visszatérések használata növelheti a teljesítményt a potenciálisan költséges másolási műveletek elkerülésével.
A fordító biztosítja, hogy a referenciaváltozók ne lépik túl a hivatkozási értékét, és az egész élettartama alatt érvényesek maradnak. További információ: A C# nyelvi specifikációjának Ref safe contexts szakasza.
A mezőkkel kapcsolatos információkért ref
tekintse meg a ref
struktúratípusokról szóló cikk Mezők szakaszátref
.
hatókörű hiv
A környezetfüggő kulcsszó scoped
egy érték élettartamát korlátozza. A scoped
módosító a ref-safe-to-escape vagy safe-to-escape élettartamot az aktuális metódusra korlátozza. A módosító hozzáadása scoped
gyakorlatilag azt állítja, hogy a kód nem hosszabbítja meg a változó élettartamát.
Paraméterre vagy helyi változóra is alkalmazható scoped
. A scoped
módosító paraméterre és helyire akkor alkalmazható, ha a típus egy ref struct
. Ellenkező esetben a scoped
módosító csak helyi referenciaváltozókra alkalmazható. Ide tartoznak a ref
módosítóval deklarált helyi változók és a in
módosítókkal ref
out
deklarált paraméterek.
A scoped
módosító implicit módon hozzáadódik this
egy , out
paraméterben és ref
paraméterben struct
deklarált metódusokhoz, ha a típus egy ref struct
.
C# nyelvspecifikáció
További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:
A módosítóról további scoped
információt az Alacsony szintű szerkezetfejlesztések javaslati megjegyzésében talál.