선언문

선언문은 새 지역 변수, 로컬 상수 또는 로컬 참조 변수를 선언합니다. 지역 변수를 선언하려면 해당 형식을 지정하고 해당 이름을 제공합니다. 다음 예제와 같이 한 문에서 동일한 형식의 여러 변수를 선언할 수 있습니다.

string greeting;
int a, b, c;
List<double> xs;

선언문에서 초기 값을 사용하여 변수를 초기화할 수도 있습니다.

string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();

앞의 예제에서는 변수의 형식을 명시적으로 지정합니다. 컴파일러가 초기화 식에서 변수 형식을 유추하도록 할 수도 있습니다. 이렇게 하려면 형식 이름 대신 키워드(keyword) 사용합니다 var . 자세한 내용은 암시적으로 형식화된 지역 변수 섹션을 참조 하세요 .

로컬 상수 선언하려면 다음 예제와 같이 키워드(keyword) 사용합니다 const .

const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;

로컬 상수도 선언할 때 초기화해야 합니다.

로컬 참조 변수에 대한 자세한 내용은 참조 변수 섹션을 참조하세요 .

암시적으로 형식화된 지역 변수

지역 변수를 선언할 때 컴파일러가 초기화 식에서 변수의 형식을 유추하도록 할 수 있습니다. 이렇게 하려면 형식 이름 대신 키워드(keyword) 사용합니다 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]

앞의 예제에서 알 수 있듯이 암시적으로 형식화된 지역 변수는 강력한 형식입니다.

참고 항목

활성화된 nullable 인식 컨텍스트에서 사용하고 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 패턴에 사용됩니다.

참조 변수

지역 변수를 선언하고 변수의 형식 앞에 키워드(keyword) 추가 ref 하면 참조 변수 또는 로컬을 ref 선언합니다.

ref int alias = ref variable;

참조 변수는 참조 변수라고 하는 다른 변수를 참조하는 변수입니다. 즉, 참조 변수는 참조에 대한 별칭입니다. 참조 변수에 값을 할당하면 해당 값이 참조 항목에 할당됩니다. 참조 변수의 값을 읽으면 참조 변수의 값이 반환됩니다. 다음 예제에서는 해당 동작을 보여줍니다.

int a = 1;
ref int alias = ref a;
Console.WriteLine($"(a, alias) is ({a}, {alias})");  // output: (a, alias) is (1, 1)

a = 2;
Console.WriteLine($"(a, alias) is ({a}, {alias})");  // output: (a, alias) is (2, 2)

alias = 3;
Console.WriteLine($"(a, alias) is ({a}, {alias})");  // output: (a, alias) 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 safe 컨텍스트 섹션을 참조하세요.

필드에 대한 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 대한 자세한 내용은 하위 수준 구조체 개선 제안 참고를 참조하세요.

참고 항목