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 vargyakran 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.varforeach

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 maxfrissí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 inmódosítókkal refout deklarált paraméterek.

A scoped módosító implicit módon hozzáadódik this egy , out paraméterben és ref paraméterben structdeklará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.

Lásd még