[CS] 메소드



참조에 의한 매개 변수 전달

우선, 참조에 의한 매개 변수 전달은 매개 변수가 메소드에 넘겨진 원본 변수를 직접 참조하게 된다. 따라서 메소드 안에서 매개 변수의 값을 수정하면 이 매개 변수가 참조하고 있는 원본 변수도 수정이 이루어진다.

C#에서 참조에 의한 매개 변수 전달은 ref 키워드를 사용하면 된다.

예시를 보자.

using System;
using System.Collections;

namespace ConsoleApp6
{
    internal class Program
    {
        static void Swap(ref int a, ref int b)
        {
            int temp = a;
            a = b;
            b = temp;
        }
        static void Main(string[] args)
        {
            int x = 3;
            int y = 4;

            Console.WriteLine($"x:{x}, y:{y}");

            Swap(ref x, ref y);

            Console.WriteLine($"x:{x}, y:{y}");
        }
    }
}

image

위와 같이 메소드의 파라미터에 ref 키워드를 자룔형 앞에 붙이고, 메소드를 호출 할 때 매개 변수 앞에도 ref를 붙여주면 된다.

메소드의 결과를 참조로 반환하기

참조 반환값을 이요하면 메소드의 호출자로 하여금 반환받은 결과를 참조로 다룰 수 있게 된다.

이러한 메소드를 선언하는 방법은 아래와 같다.

class SomeClass
{
    int SomeValue=10;
    public ref int SomeMethod(){
        
        return ref SomeValue;
    }
}

ref 한정자를 이용해서 메소드를 선언하고, return 문이 반환하는 변수 앞에도 ref를 붙여주면 된다.

참조로 반환하는 메소드는 다음과 같이 호출이 가능하다.

SomeClass obj - new SomeClass();
int result = obj.SomeMethod; 

SomeMethod()는 참조로 반환하도록 구현됐지만, 호출자가 특별한 키워드를 사용하지 않고 한 값으로 반환하는 평범한 메소드 처럼 동작한다.

SomeMethod()가 반환하는 결과를 호출자가 참조로 받고 싶으면 아래와 같이 사용하면 된다.

SomClass obj=new SomeClass;
ref int result = ref obj.SomeMethod();

위와 같이 결과를 담는 지역 변수와 호출할 메소드의 이름 앞에 ref 키워드를 위치시켜야 한다.

예제를 보자.

using System;
using System.Collections;

namespace ConsoleApp6
{
    class Product
    {
        private int price = 100;

        public ref int GetPrice()
        {
            return ref price;
        }

        public void PrintPrice()
        {
            Console.WriteLine($"Price : {price}");
        }
    }
    internal class Program
    {
        
        static void Main(string[] args)
        {
            Product carrot = new Product();
            ref int ref_local_price= ref carrot.GetPrice();     // ref_local_price를 수정하면 carrot.price도 바뀐다.
            int normal_local_price=carrot.GetPrice();

            carrot.PrintPrice();
            Console.WriteLine($"Ref Local price : {ref_local_price}");
            Console.WriteLine($"Normal Local Price : {normal_local_price}");

            ref_local_price = 200;
            carrot.PrintPrice();
            Console.WriteLine($"Ref Local price : {ref_local_price}");
            Console.WriteLine($"Normal Local Price : {normal_local_price}");
        }
    }
}

image

클래스의 멤버변수를 Main()함수에서 바꾸는 모습을 볼 수 있다.

출력 전용 매개 변수

보통 메소드의 결과는 하나면 충분하지만 예외의 경우 두 개 이상의 결과를 요구하는 경우가 있다. 물론 ref 키워드를 통해 두 개 이상의 결과를 얻어 올 수 있지만 C#은 좀 더 안전한 방법으로 똑같은 일을 하게 해주는 키워드가 있다, 바로 out 키워드 이다. 이 out 키워드가 출력 전용 매개 변수에 쓰이는 키워드이다. 사용 방법은 간단하다. 메소드의 선언부와 호출부에 ref 키워드 대신 out 키워드를 사용하면 된다. ref를 이용해서 두 개 이상의 결과를 반환하게 하는 메소드와 out 키워드를 이용해 두 개 이상의 결과를 반환하는 메소드의 예시를 보자.

ref 키워드

void Divide(int a, int b, ref int quotient, ref int remainder)
{
    quotient = a / b;
    remainder = a % b;
}

int a=10;
int b=3;
int c=0;
int d=0;

Divide(a,b,ref c, ref d);

Console.WriteLine("Quotient : {0}, Remainder : {1}",c,d);

out 키워드

void Divide(int a, int b, out int quotient, out int remainder)
{
    quotient = a / b;
    remainder = a % b;
}

int a=10;
int b=3;
int c;
int d;

Divide(a,b,out c, out d);

Console.WriteLine("Quotient : {0}, Remainder : {1}",c,d);

키워드만 바뀌었지 코드는 똑같다. 하지만 out에는 ref에는 없는 안전장치가 있다. 예를 들어 ref 키워드를 이용해서 매개 변수를 넘기는 경우에는 메소드가 해당 매개 변수에 결과를 저장하지 않아도 컴파일러는 아무런 경고를 하지 않지만, out 키워드를 이용해서 매개 변수를 넘기는 경우에 메소드가 해당 매개 변수에 결과를 저장하지 않으면 컴파일러가 에러 메세지를 출력한다. 즉, 개발자의 의도대로 동작하게 만들어 주는 것이다. 개발자가 두 개 이상의 앖을 원해서 ref를 통해서 매개 변수를 넘겼는데 메소드안에서 그에 맞는 코드가 없어도 에러가 발생하지 않기 때문에 ref 키워드로 두 개 이상의 결과를 얻으려하면 에러가 발생할 여지를 남기기 때문에 out 키워드를 통해 안전하게 사용하는 것이 맞다.

가변길이 매개 변수

프로그래밍을 하다보면 매개 변수의 수가 다르다는 이유로 똑같은 메소드를 여러가지 버전으로 오버로딩해야 할 때가 있다. 이런 경우를 위해 C#은 가변 길이 매개 변수라는 기능을 제공한다.

가변길이 매개 변수란, 그 개수가 유연하게 변할 수 있는 매개 변수를 말한다. 이것을 이용하면 다음과 같은 코드를 사용할 수 있게 된다.

int total =0;

total = Sum(1,2);
total = Sum(1,2,3);
total = Sum(1,2,3,4,5,6,7,8,9);
// ...

가변길이 매개 변수는 params 키워드와 배열을 이용해서 선언한다. 예시를 보자.

int Sum(params int[] args) // Sum() 메소드에 입력한 모든 매개 변수는 args 배열에 담긴다.
{
    int sum=0;
    
    for(int i=0,i<args.Length;i++)
    {
        sum+=args[i];
    }
    return sum;
}

가변길이 매개 변수는 형식은 같으나 매개 변수의 개수만 유연하게 달라질 수 있는 경웨 적합하다.

명명된 매개 변수

기본적으로 메소드를 호출할 때 매개 변수 목록 중 어느 매개 변수에 데이터를 할당할 것인지는 순서가 결정한다. 하지만 C#은 다른 방법도 제공한다. 그것이 명명된 매개 변수이다. 말 그대로 메소드를 호출할 때 매개 변수의 이름에 근거해서 데이터를 할당하는 것이다. 명명된 매개 변수를 사용하기 위해서 메소드의 선언부분을 고칠 필요는 전혀 없다. 단지 메소드를 호출할 때 매개 변수의 이름 뒤에 콜론( : )을 붙인 뒤 그 뒤에 할당할 데이터를 넣어주면 된다. 예시를 보자.

static void PrintProfile(string name, string phone)
{
    Console.WriteLine("Name:{0}, Phone:{1}",name, phone);
}
static void Main()
{
    PrintProfile(name : "박찬호", phone : "010-1234-5678");
}

명명된 매개 변수는 코드가 읽기 쉬워진다. 메소드가 많은 수의 매개 변수를 요구할 때 사용하면 좋다.




© 2022. by KSC

Powered by sora