선언문
선언문은 새 지역 변수, 지역 상수 또는 지역 참조 변수를 선언합니다. 지역 변수를 선언하려면 해당 형식을 지정하고 해당 이름을 제공합니다. 다음 예제와 같이 한 문에서 동일한 형식의 여러 변수를 선언할 수 있습니다.
string greeting;
int a, b, c;
List<double> xs;
선언문에서 초기 값을 사용하여 변수를 초기화할 수도 있습니다.
string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();
앞의 예제에서는 변수의 형식을 명시적으로 지정합니다. 컴파일러가 초기화 식에서 변수 형식을 유추하도록 할 수도 있습니다. 이렇게 하려면 형식 이름 대신 var
키워드를 사용합니다. 자세한 내용은 암시적 형식 지역 변수 섹션을 참조하세요.
지역 상수를 선언하려면 다음 예제와 같이 const
키워드를 사용합니다.
const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;
지역 상수도 선언할 때 초기화해야 합니다.
지역 참조 변수에 대한 자세한 내용은 참조 변수 섹션을 참조하세요.
암시적 형식 지역 변수
지역 변수를 선언할 때 컴파일러가 초기화 식에서 변수의 형식을 유추하도록 할 수 있습니다. 이렇게 하려면 형식 이름 대신 var
키워드를 사용합니다.
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]
앞의 예제에서 알 수 있듯이 암시적 형식 지역 변수는 강력한 형식입니다.
참고 항목
활성화된 null 허용 인식 컨텍스트에서 var
을 사용하고 초기화 식의 형식이 참조 형식인 경우 초기화 식의 형식이 null을 허용하지 않는 경우에도 컴파일러는 항상 null 허용 참조 형식을 유추합니다.
var
은 일반적으로 생성자 호출 식과 함께 사용됩니다. var
를 사용하면 다음 예제와 같이 변수 선언 및 개체 인스턴스화에서 형식 이름을 반복하지 않을 수 있습니다.
var xs = new List<int>();
대상 형식 new
식을 대신 사용할 수 있습니다.
List<int> xs = new();
List<int>? ys = new();
무명 형식을 사용하는 경우 암시적 형식화 지역 변수를 사용해야 합니다. 다음 예제에서는 무명 형식을 사용하여 고객의 이름 및 전화번호를 보유하는 쿼리 식을 보여줍니다.
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}");
}
앞의 예제에서는 fromPhoenix
변수의 형식을 명시적으로 지정할 수 없습니다. 형식은 IEnumerable<T>이지만 이 경우 T
는 무명 형식이므로 해당 이름을 제공할 수 없습니다. 이 때문에 var
을 사용해야 합니다. 같은 이유로 foreach
문에서 customer
반복 변수를 선언할 때 var
을 사용해야 합니다.
암시적 형식 지역 변수에 대한 자세한 내용은 암시적 형식 지역 변수를 참조하세요.
패턴 일치에서 var
키워드는 var
패턴에 사용됩니다.
참조 변수
지역 변수를 선언하고 변수의 형식 앞에 ref
키워드를 추가할 때 참조 변수 또는 ref
지역을 선언합니다.
ref int aliasOfvariable = ref variable;
참조 변수는 참조 대상(referent)이라고 하는 다른 변수를 참조하는 변수입니다. 즉, 참조 변수는 해당 참조 대상에 대한 별칭입니다. 참조 변수에 값을 할당하면 해당 값이 참조 대상에 할당됩니다. 참조 변수의 값을 읽으면 참조 대상의 값이 반환됩니다. 다음 예제에서는 해당 동작을 보여줍니다.
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
대입 연산자 = ref
를 사용하여 참조 변수의 참조 대상을 변경합니다.
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
앞의 예제에서 element
참조 변수는 첫 번째 배열 요소에 대한 별칭으로 초기화됩니다. 그런 다음 마지막 배열 요소를 참조하도록 ref
가 다시 할당됩니다.
ref readonly
지역 변수를 정의할 수 있습니다. ref readonly
변수에는 값을 할당할 수 없습니다. 그러나 다음 예제와 같이 이러한 참조 변수를 ref
재할당할 수 있습니다.
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
다음 예제와 같이 참조 변수에 참조 반환을 할당할 수 있습니다.
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
}
}
앞의 예제에서 GetReferenceToMax
메서드는 참조로 반환(return-by-ref) 메서드입니다. 최대값 자체는 반환하지 않지만 최대값을 보유하는 배열 요소에 대한 별칭인 참조 반환입니다. Run
메서드는 max
참조 변수에 참조 반환을 할당합니다. 그런 다음 max
에 할당하여 store
인스턴스의 내부 스토리지를 업데이트합니다. ref readonly
메서드를 정의할 수도 있습니다. ref readonly
메서드의 호출자는 해당 참조 반환에 값을 할당할 수 없습니다.
foreach
문의 반복 변수는 참조 변수일 수 있습니다. 자세한 내용은 반복 문 문서의 foreach
문 섹션을 참조하세요.
성능이 중요한 시나리오에서 참조 변수 및 반환을 사용하면 잠재적으로 비용이 많이 들 수 있는 복사 작업을 방지하여 성능이 좋아질 수 있습니다.
컴파일러는 참조 변수가 참조 대상보다 오래 유지되지 않고 전체 수명 동안 유효한 상태를 유지하도록 합니다. 자세한 내용은 C# 언어 사양의 ref 안전 컨텍스트 섹션을 참조하세요.
ref
필드에 대한 자세한 내용은 ref
구조체 형식 문서의 ref
필드 섹션을 참조하세요.
scoped ref
상황별 키워드 scoped
는 값의 수명을 제한합니다. scoped
한정자는 ref-safe-to-escape 또는 safe-to-escape 수명을 각각 현재 메서드로 제한합니다. 실질적으로 scoped
한정자 추가는 코드가 변수의 수명을 연장하지 않는다는 어설션입니다.
scoped
는 매개 변수 또는 지역 변수에 적용할 수 있습니다. 형식이 ref struct
인 경우 매개 변수 및 지역 변수에 scoped
한정자를 적용할 수 있습니다. 그렇지 않으면 scoped
한정자는 지역 참조 변수에만 적용될 수 있습니다. 여기에는 ref
한정자를 사용하여 선언된 지역 변수와 in
, ref
또는 out
한정자를 사용하여 선언된 매개 변수가 포함됩니다.
scoped
한정자는 형식이 ref struct
인 경우 struct
에 선언된 메서드의 this
, out
매개 변수 및 ref
매개 변수에 암시적으로 추가됩니다.
C# 언어 사양
자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.
scoped
한정자에 대한 자세한 내용은 하위 수준 구조체 개선 제안 참고 사항을 참조하세요.
참고 항목
.NET