본문 바로가기
- C#/C# is 도샵

[C#] ref, out, in 키워드

by david_동근 2025. 8. 30.

C# 에서 매개변수로 value 타입 값을 전달할 때, 보통 call by value 입니다.


 

ref, out, in 키워드를 전부 매개변수 한정자라고 부릅니다. ref 부터 설명하겠습니다.

ref

하지만 ref 키워드를 사용하게 되면 value 타입도 call by reference 로, 참조 전달됩니다.

호출한 쪽의 변수를 참조로 넘겨서, 넘겨 받은 메서드 안에서 값을 변경했을 시,

호출한 원본 쪽에서도 값의 변경이 반영되도록 하는 것입니다.

다시말해 "호출한 놈의 변수를 수정할 수 있다!" 가 특징이 되겠습니다.

 

아래 간단한 pseudo 코드로 확인하겠습니다.

void AddOne(ref int x) // 시그니처에 ref 키워드
{
    x += 7;              // 호출한 놈의 변수도 변경
}

int n = 10;
AddOne(ref n);           // 호출할 때도 ref

// n == 17

 

reference 타입 (참조형) 도 기본적으로 참조값을 값으로 전달합니다.

그래서 메서드 안에서 new 객체를 할당해도 호출한 쪽의 변수는 바뀌지 않습니다.

아래처럼 ref 를 사용해 그 변수 자체를 바꿔주겠습니다.

void StrBldr(StringBuilder sb) { sb = new StringBuilder("NEW"); } // 호출한 놈의 변수는 그대로
void StrBldr_Ref(ref StringBuilder sb) { sb = new StringBuilder("NEW"); } // 호출한 놈의 변수도 NEW 로 변경

var sb1 = new StringBuilder("OLD");
StrBldr(sb1);
// sb1 == "OLD"

var sb2 = new StringBuilder("OLD");
StrBldr_Ref(ref sb2);
// sb2 == "NEW"

 

ref 는 value 타입을 복사 없이 그 제자리에서 변경 가능하다는 점에서 유용합니다.

호출하기 전에 꼭 할당해 놓는 것을 잊으시면 안됩니다.

 

 

out

out 또한 매개변수가 call by reference 로 전달이 되며,

out 키워드를 사용한 매개변수의 메서드 안에서는 무조건 값이 할당 되어야 합니다.

ref 와 달리 호출 전에 초기화 할 필요 없습니다.

bool TryDivide(int a, int b, out int result)
{
    if (b == 0)
    {
        result = 0; // 무조건 메서드 안에서 값 할당이 꼭 있어야 함다
        return false;
    }
    result = a / b;
    return true;
}

int q; // 초기화 해도 되고, 안해도 됩니다용
if (TryDivide(10, 2, out q)) // 호출할 때도 out 을 씁니다요
{
    // q 는 5 이겠죵?
}

 

아참, out 도 ref 처럼 프로퍼티나 상수 등은 안되고 변수만 가능하답니다.

 

 

in

in 또한 매개변수가 call by reference 로 전달이 되며,

in 키워드가 있는 매개변수는 값 수정이 불가 (읽기전용 이지요) 합니다.

public readonly struct Vec3
{
    public readonly float X, Y, Z;
    public Vec3(float x, float y, float z) => (X, Y, Z) = (x, y, z);

    // 읽기 전용 메서드
    public readonly float LengthSq() => X*X + Y*Y + Z*Z;
}

float DistanceSq(in BigVec3 a, in BigVec3 b) // 값 복사 없이 읽기 전용 참조
{
    // a.X = 0; // 노노노노노!!!! 땡땡땡~ in 파라미터는 값을 바꿀 수 없당게요~
    float dx = a.X - b.X;
    float dy = a.Y - b.Y;
    float dz = a.Z - b.Z;
    return dx*dx + dy*dy + dz*dz;
}

 

메서드가 해당 값을 절대 수정하지 않음을 보장받으며,

위 처럼 조금 커더란 데이터 구조체의 복사를 피할 수 있습니다.

 


 

아~ 간단하게 알아본 ref, out, in 키워드 였습니다.

그럼 다들 좋은 하루되세요~

안뇽~ (^⦁⩊⦁⸝⸝^)

'- C# > C# is 도샵' 카테고리의 다른 글

[C#] [Unity] C# Action 과 UnityAction  (0) 2025.11.19
[C#] Lambda Expression 람다식  (4) 2025.08.24
[C#] HashSet<T>  (1) 2025.06.17
[C#] virtual abstract interface  (0) 2025.05.20
[C#] System.Array & Copy  (0) 2025.05.12