* ref

 

ref 키워드는 C#에서 참조에 의한 전달로 인수를 전달할 때, 메소드 결과를 참조로 반환할 때 사용된다.

 

 

- 참조에 의한 전달

 

값에 의한 전달이 매개변수가 변수나 상수로부터 값을 복사하는 것과 달리 참조에 의한 전달한 매개변수가 메소드에 넘겨진 원본 변수를 직접 참조한다. 만약 메소드 안에서 매개변수를 수정하면 이 매개변수가 참조하고 있는 원본 변수에 수정이 이루어진다.

static void Swap(ref int a, ref int b)
{
    // 원본에 반영된다.
    int temp = a;
    a = b;
    b = temp;
}

static void Main(string[] args)
{
    int a = 3;
    int b = 2;
    Swap(ref a, ref b);
}

 

 

- 참조로 반환

 

메소드의 반환형으로 ref를 지정할 수도 있는데, 방식에 따라 참조나 값으로 반환 값을 받아서 사용할 수 있다. 참조로 받으면 당연히 원본도 같이 수정된다.

// 지역 변수가 반환될 수 없도록 컴파일러가 잘 잡아낸다.

class MyRefClass
{
    public MyRefClass(int value) { this.value = value; }
    public ref int getValueRef() { return ref value; }

    private int value;
}

static void Main(string[] args)
{
    MyRefClass myRef = new MyRefClass(3);
            
    // 참조를 반환할 때 사용
    ref int valueRef = ref myRef.getValueRef();
    valueRef = 2; // 원본에 반영

    // 값을 반환할 때 사용
    int value = myRef.getValueRef();
}

 

 

* out

 

out 키워드는 C#에서 반환해야할 값이 2개 이상일 때 사용한다. out 키워드를 붙여서 반환 받을 변수들을 메소드에 인수로 전달하고 메소드 내에서 매개변수에 결과를 저장하면 매개변수가 참조하고 있는 원본 변수들이 수정된다. 호출 이후에 결과가 저장된 변수들을 사용하면 된다.

static void MaxMin(int a, int b, out int max, out int min)
{
    // out 키워드 덕분에 max, min은 초기화를 보장받는다.
    if(a < b)
    {
        max = b;
        min = a;
    }
    else
    {
        max = a;
        min = b;
    }
}

static void Main(string[] args)
{
    int max; int min;
    MaxMin(2, 3, out max, out min);
}

 

ref 키워드를 통해서도 똑같이 구현할 수 있지만 out 키워드는 안전 장치가 존재한다. 

 

out 키워드를 사용할 경우 해당 매개변수에 결과를 저장하지 않으면 컴파일 에러가 발생하기 때문에 안정적으로 프로그래밍 할 수 있다. 이러한 강제성 out 키워드를 가진 매개변수는 초기화를 보장받을 수 있다. 따라서 인수로 초기화되지 않은 변수를 넘겨줄 수 있다. (ref는 초기화되지 않은 변수를 넘겨줄 수 없다.)

 

 

* ref vs out

 

ref out
ref로 넘겨주기 전에 변수를 초기화해야 한다. out로 넘겨주기 전에 변수를 초기화하지 않아도 된다.
메소드를 리턴하기 전에 매개변수 값을 초기화할 필요 없다. 메소드를 리턴하기 전에 매개변수 값을 초기화해야 한다.
호출된 메소드가 전달된 매개변수의 값도 변경해야할 때 유용하다. 메소드가 여러 값을 반환할 때 유용하다.
양방향 전달 단방향 전달
참조를 반환할 수 있다.  

 

'C#' 카테고리의 다른 글

[C#] abstract class vs interface  (0) 2022.06.28
[C#] const, readonly  (0) 2022.06.28
[C#] 강력한 형식 언어(Strongly Typed Language)  (0) 2022.06.28
[C#] var  (0) 2022.06.28
[C#] 박싱과 언박싱(Boxing and Unboxing)  (0) 2022.06.28

+ Recent posts