[C# 객체지향] 타입 유형 확장5_ref와 out

eunjin lee·2022년 7월 12일
0

C# 9.0 프로그래밍

목록 보기
13/50

참조에 의한 호출(CBR : call by reference)을 지원하기 위해 ref 예약어와 out 예약어가 있다.


  1. ref 예약어
  • 클래스처럼 얕은 복사로 전달한 것과 같은 동일한 효과를 낸다.

✍ 샘플 코드

    class Program
    {
        static void Main(string[] args)
        {
            int x = 6;
            Change(x);
            Console.WriteLine(x);

            int y = 10;
            refChange(ref y);
            Console.WriteLine(y);
        }

        static void Change(int param)
        {
            param = 0;
        }
        
        static void refChange(ref int param)
        {
            param = 0;
        }
    }

✅ 결과

6
0
  • 그러나 클래스 복사처럼 스택에 같은 주소값을 복사해 저장하는 것이 아니라, 아예 동일한 메모리를 가리키기 때문에 같은 주소값을 가리킨 것이다.
  • 반드시 호출할 때 null이든 new든 어떤 값이라도 할당해야 ref인자로 전달이 가능하다.(struct의 경우 모든 값이 초기화되어야 한다.)

✍ 샘플 코드

    class Program
    {
        static void Main(string[] args)
        {
            Point a = new Point(10, 12);
            Point b = new Point(4, 33);

            Change(a);
            refChange(ref b);
            Console.WriteLine(a.x+", "+a.y);//Point a가 가리키는 값
            Console.WriteLine(b.x+", "+b.y);//Point b(=Point p)가 가리키는 값
        }

        static void Change(Point p)
        {
            p = new Point();//Point p가 새로운 주소값을 가리키게 됨.
            p.x = 0;
            p.y = 0;

        }

        static void refChange(ref Point p)
        {
            p = new Point();//Point p(=Point b)가 새로운 주소값을 가리키게 됨.
            p.x = 0;
            p.y = 0;
        }
    }

    class Point
    {
        public int x;
        public int y;

        public Point()
        {
        }
        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

✅ 결과

10, 12
0, 0
  1. out 예약어
  • ref와 달리 초기화가 필요하지 않으며, 초기화돼 있더라도 out 인자를 받는 메서드에서는 그 값을 사용할 수 없다.
  • ref와 달리 out으로 지정된 인자를 받는 메서드는 변수에 값을 넣어 반환해야 한다.
  • ref는 호출하는 측에서 의미 있는 값을 전달한다면 (호출되는 메서드에서도 의미 있는 값 할 당 가능), out은 호출되는 메서드 측에서 반드시 값을 할당하여 의미 있는 값을 반환한다.

✍ 샘플 코드

    class Program
    {
        static void Main(string[] args)
        {
            int num;

            if (Divide(10, 5, out num))
            {
                Console.WriteLine(num);
            }


            if (Divide(10, 0, out num)) //false
            {
                Console.WriteLine(num);
            }

            if (Divide(0, 10, out num))
            {
                Console.WriteLine(num);
            }
        }
                
        static bool Divide(int x, int y, out int result)
        {
            if (y == 0)
            {
                result = 0;
                return false;
            }

            result = x / y;
            return true;
        }
    }

✅ 결과

2
0

0개의 댓글