NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 15-5. 메서드의 파라메터를 참조로 전달하기 위한 ref 키워드

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 오늘은 메서드의 파라메터(인수)를 값의 복사가 아닌 참조로 전달 되도록 할 수 있는 방법에 대해서 알아보겠습니다.

     

    값 타입의 인수를 참조로 전달하는 경우 호출된 메서드의 매개 변수 변경 내용이 호출 메서드에 반영됩니다. 예를 들어 호출자가 로컬 변수 또는 배열의 요소를 전달하는 경우 호출된 메서드에서 ref 인자(매개 변수)가 참조하는 개체를 바꾸면 호출자의 로컬 변수 또는 배열의 요소가 새 개체를 참조합니다.

     

    아직, "값 형식"과 "참조 형식"에 대해 설명하지 않았기에 Boxing과 Unboxing 프로세스도 배우지 않았습니다. 아주 중요한 내용이기에 꼭 정확하게 이해하고 넘어가야 합니다. 여기에서 설명하는 ref를 이용한 참조와 "참조 형식"의 개념을 혼동하면 안됩니다. 매서드의 매개 변수는 "값 형식"이든 "참조 형식"이든 관계없이 ref로 수정될 수 있습니다. 참조로 전달되는 경우 값 형식은 Boxing되지 않습니다.

     

    ※ Boxing, Unboxing에 대해서는 다음 강좌에서 자세하게 알아보도록 하겠습니다.

     

    아래는 값 형식을 참조로 전달하는 경우와 아닌 경우를 비교한 내용입니다.

    using System;
    namespace SwapByRef
    {
        class MainApp
        {
            static void Swap(ref int a, ref int b)
            {
                int temp = b;
                b = a;
                a = temp;
            }
     
            static void Main(string[] args)
            {
                int x = 3;
                int y = 4;
                Console.WriteLine("x:{0}, y:{1}", x, y);
                Swap(ref x, ref y);
                Console.WriteLine("x:{0}, y:{1}", x, y);
            }
        }
    }

     

     

    ref를 이용하여 값 형식을 참조로 전달한 후 Console 출력하면 다음과 같은 결과를 얻을 수 있습니다. ref 매개 변수를 사용하려면, 메서드 정의와 호출 양쪽 모두 ref 키워드를 명시적으로 사용해야 합니다. 또한, ref 매개 변수에 전달되는 인수는 전달 되기 전에 반드시 초기화해야 합니다. 이러한 방식은 인수를 전달하기 전에 명시적으로 초기화할 필요가 없는 out과 다른점입니다.

    ※ out 키워드는 다음 강좌에서 진행합니다.

    uvPQ5H3.png

     

     

    ref를 사용하지 않은 코드입니다.

    using System;
    namespace SwapByValue
    {
        class MainApp
        {
            public static void Swap(int a, int b)
            {
                int temp = b;
                b = a;
                a = temp;
            }
     
            static void Main(string[] args)
            {
                int x = 3;
                int y = 4;
                Console.WriteLine("x:{0}, y:{1}", x, y);
                Swap(x, y);
                Console.WriteLine("x:{0}, y:{1}", x, y);
            }
        }
    }

     

     

    다음은 위의 코드 결과입니다.

    VCKPnX8.png

     

     

    ref 키워드를 사용하면 비동기 한정자를 사용하여 정의된 메서드와 yield return, yield break문을 포함하는 반복기 메서드를 사용할 수 없게 됩니다. 

    아래는 "참조 형식"을 ref로 전달하는 경우의 결과를 보여주는 예제입니다.

    using System;
    namespace ChangeByReference
    {
        class RefExample2
        {
            static void ChangeByReference(ref Product itemRef)
            {
                itemRef = new Product("Stapler", 99999);
                itemRef.ItemID = 12345;
            }
     
            static void Main()
            {
                Product item = new Product("Fasteners", 54321);
                System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
                ChangeByReference(ref item);
                System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
            }
        }
     
        class Product
        {
            public Product(string name, int newID)
            {
                ItemName = name;
                ItemID = newID;
            }
     
            public string ItemName
            {
                get; set;
            }
     
            public int ItemID
            {
                get; set;
            }
        }
    }

     

     

    결과는 다음과 같습니다.

    SlK22fv.png

     

     

    참조 형식을 참조로 전달하는 경우 호출된 메서드는 참조 매개 변수가 참조하는 호출 메서드의 개체를 변경할 수 있습니다. 개체의 저장 위치는 참조 매개 변수의 값으로 메서드에 전달됩니다. 매개 변수의 저장 위치에서 값을 변경하여 새 개체를 가리키도록 하면 호출자가 참조하는 저장 위치도 변경됩니다. 아래의 ref 키워드를 사용하지 않은 경우의 예제입니다.

    using System;
    namespace ChangeByReference
    {
        class RefExample2
        {
            static void ChangeByReference(Product itemRef)
            {
                itemRef = new Product("Stapler", 99999);
                itemRef.ItemID = 12345;
            }
     
            static void Main()
            {
                Product item = new Product("Fasteners", 54321);
                System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
                ChangeByReference(item);
                System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
            }
        }
     
        class Product
        {
            public Product(string name, int newID)
            {
                ItemName = name;
                ItemID = newID;
            }
     
            public string ItemName
            {
                get; set;
            }
     
            public int ItemID
            {
                get; set;
            }
        }
    }

     

     

    "참조 형식"에 ref를 사용하지 않을 경우의 결과는 아래와 같습니다.

    SmK5nat.png

     

     

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.