언어(C, C++, C#)

[C#] 참조 전달(pass by reference) ref, out, in

적용1 2025. 4. 30. 23:41
728x90

ref, out, in은 모두 C#에서 메서드로의 인자 전달에 사용된다. 3가지 모두 참조 전달(pass by reference) 방식으로, C나 C++에서 포인터나 참조를 직접 전달하는 방식과 유사하다.

ref

  • 변수를 참조로 전달하며, 호출하는 쪽에서 반드시 초기화되어 있어야 한다.
  • 메서드 내에서 해당 변수의 값을 읽고, 수정하여 반영할 수 있다.

  • 선언과 호출에서 모두 ref 키워드가 붙여져서 사용되어야 한다.
void Modify(ref int number)
{
    number += 10;	// number의 참조가 와서 변경하면
}

int a = 5;
Modify(ref a);
Console.WriteLine(a); // 결과로 원래 숫자에 15가 반영된다

out

  • 변수가 참조로 전달되지만, 초기화되어 있을 필요가 없다. 대신, 메서드 내에서 반드시 값을 할당해야 한다.

  • 메서드에서 값을 반환하는 출력 전용 파라미터로 사용된다.
  • ref와 마찬가지로 선언과 호출에서 모두 out 키워드가 붙여진 상태로 사용되어야 한다.
bool TryParse(string input, out int result)
{
    result = 0;		// int.Parse(input)이 실패할 때를 대비하여 미리 값을 할당
    try
    {
        result = int.Parse(input);
        return true;
    }
    catch
    {
        return false;
    }
}

int number;
if (TryParse("123", out number))
{
    Console.WriteLine(number); // 123
}

in

  • 값을 참조로 전달하지만, 읽기 전용이다.

  • 값 복사를 줄여 성능을 향상시키면서, 읽기 전용 보장을 하고 싶을 때 사용된다. 특히, C#의 경우에는 struct(구조체)와 같은 값 타입을 큰 객체로 사용할 때 유용하다.
    (C++에서 인자로 const T*, const T& 와 같이 const 포인터로 전달하는 것과 비슷한 것 같다.)
void PrintLength(in string text)
{
    Console.WriteLine(text.Length);
    // text = "changed"; // in 키워드가 붙은 매개변수는 수정할 수 없다. 따라서 주석을 해제하면 에러가 생긴다.
}

string message = "Hello";
PrintLength(in message);
728x90