Developer/C#, 닷넷

C# ref, out, return 차이

우주로그 2022. 8. 23.

1. ref, out 개요

ref와 out는 메서드에서 처리한 결과를 참조를 통해 전달을 할 때 사용을 합니다.

일단 정의상으로 이해가 잘 되지 않습니다.

그리고 메서드에서 결과값을 전달하는건 흔하게 return을 사용하면 된다고 알고 있습니다.

그럼 언제 ref와 out를 사용할까요?

먼저 우리가 알고 있는 return 샘플을 먼저 보겠습니다.

 

 

2. return

using System;
namespace ReturnEx
{
    public class Program
    {
        static int SetTwice(int no1)
        {
            no1 = no1 *2;
            return no1;
        }
        static void Main(string[] args)
        {
            int no1 = 4;
            int no1Result = SetTwice(no1);

            Console.WriteLine($"no1 result: {no1Result}");
        }
    }
}

int형 매개변수 no1을 받아 2배로 만들어주는 int형 반환 메서드 SetTwice가 있고,

해당 메서드에 4를 전달 해 8이라는 정상적인 값을 받아 왔습니다.

 

그럼 이제 이걸 ref를 사용해서 처리해보겠습니다.

using System;
namespace RefEx
{
    public class Program
    {
        static void SetTwice(ref int no1)
        {
            no1 = no1 *2;
        }
        static void Main(string[] args)
        {
            int no1 = 4;
            SetTwice(ref no1);

            Console.WriteLine($"no1 result: {no1}");
        }
    }
}

ref를 매개변수로 사용하는 경우 타입 앞에 ref를 붙여주면 됩니다.

그리고 해당 메서드를 호출할 때도 동일하게 ref를 붙여서 참조 전달을 해줍니다.

그럼 Main 메서드에서 선언한 no1의 참조값이 전달이 되서, SetTwice 메서드에서는 Main의 no1 값을 변경하게 되는 것입니다.

 

3. return 대신 ref, out 를 사용하는 이유

 

결론은 반환 값이 2개 이상 필요한 경우 ref, out를 활용할 수 있습니다.

위 예제에서 2배 만드는 SetTwice 함수가 2개 매개변수를 자기고, 각각 2배 해서 결과를 줘야 한다고 해보죠.

return은 1개의 값만 반환할 수 있기 때문에 불가능하며, ref를 사용해야 합니다.

(out을 사용하면 에러가 나는데, 이건 뒤 ref와 out 차이에서 다시 설명하겠습니다.)

 

using System;
namespace RefEx
{
    public class Program
    {
        static void SetTwice(ref int no1, ref int no2)
        {
            no1 = no1 *2;
            no2 = no2 *2;
        }
        static void Main(string[] args)
        {
            int no1 = 4;
            int no2 = 5;
            SetTwice(ref no1, ref no2);

            Console.WriteLine($"no1 result: {no1}, no2 result :{no2}");
        }
    }
}

no1과 no2를 ref 매개변수로 넘겨서 다중으로 결과를 가져올 수 있습니다.

 

 

4. ref, out 차이

- ref :  호출하는 메서드 내에서 매개변수 초기화를 한 후 호출받는 메서드로 참조 전달을 해야 합니다.

- out : 호출하는 메서드 내에서 매개변수 초기화는 의미가 없고, 호출받는 메서드 내에서 초기화를 해야 합니다.

 

위 예제에서처럼 ref는 오출하는 Main 메서드에서 no1, no2를 초기화 했습니다.

만약 ref 대신에 out를 사용했다면 오류가 발생합니다.

그 이유는 호출받는 SetTwice에서 no1, no2를 초기화 하는 부분이 없기 때문입니다.

 

언제 어떤걸 사용하는지는 어떻게 구분할까요?

- ref : 전달하는 매개변수가 호출받는 함수를 통해서 값을 변경해서 사용하는 경우

- out : 호출받는 함수에서 새로운 값을 받아서 사용하는 경우

 

이제 out의 예제를 보겠습니다.

using System;
namespace RefEx
{
    public class Program
    {
        static void SetTwice(int no1, out int no2, out int no3)
        {
            no2 = no1 * 2;
            no3 = no1 * 3;
        }
        static void Main(string[] args)
        {
            int no1 = 4;
            int no2;
            int no3;
            SetTwice(no1, out no2, out no3);

            Console.WriteLine($"no2 result: {no2}, no2 result :{no3}");
        }
    }
}

no2, no3는 SetTwice에서 초기화를 하고, 그 결과를 Main no2, no3에 전달하게 됩니다.

 

 

 

 

 

 

 

 

 

 

 

댓글