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 max
programu , 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ę ref
ref
pó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ą in
ref
modyfikatora lub out
.
Modyfikator scoped
jest niejawnie dodawany do this
metod zadeklarowanych w struct
parametrach , 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.