본문 바로가기
유니티 공부/C# 문법

C# - 파라미터 전달방식(ref, out, in 키워드), Pass by Value(값에 의한 전달) 및 Pass by Reference(참조에 의한 전달)

by 코딩하는 돼징 2023. 12. 14.
반응형

1. Pass by Value(값에 의한 전달)

파라미터 "값"을 복사해서 파라미터 값 자체를 복사해서 전달하는 방식이다. 

만약 몰래 소주를 마셔서 이를 물로 채워넣는다는 예시로 코드를 작성해보자

class change
{
    public void changeToWater(int leftsoju)
    {
        int water = 100;
        leftsoju = water;
    }
}

public static void Main()
{
    int leftvalue = 0; // 소주를 다 마신 상태
    chang Change = new chang(); 
    Change.changeToWater(leftvalue) // 마신 소주에 물 넣기
    Console.WriteLine(leftsoju);
}

값을 복사해서 전달하기 때문에  weight2와 weight는 별도로 2개의 메모리 영역을 가지게 된다. 그러므로 weight2의 값을 변경하더라도 weight는 변경되지 않는다.

static void Pig(int weight2)
{
    weight2 += 100;
    Console.WriteLine(weight2);
}

public static void Main()
{
    int weight = 10; 
    Pig(weight);
    Console.WriteLine(weight);
}

 


2. Pass by Reference(참조에 의한 전달)

변수에 대한 액세스를 해당 변수의 메모리 주소를 전달하여 메모리를 공유하는 것을 의미한다.

01 ref (read-write)

ref 키워드를 사용하면 함수가 변수의 원본에 직접 접근하여 수정할 수 있다. 즉 메서드 내부에서 해당 변수를 변경하면, 호출한 쪽의 변수에도 변경 사항이 반영된다. 단 ref 매개변수는 전달하기 전에 반드시 초기화되어 있어야 한다. 이는 함수 내부에서 값을 읽을 수도 있기 때문이다. 보통은 함수에서 호출자의 변수 값을 직접 수정해야 할 때 ref를 사용한다

static void Pig(ref int weight2)
{
    weight2 += 100;
    Console.WriteLine(weight2);
}

public static void Main()
{
    int weight = 10;
    Pig(ref weight);
    Console.WriteLine(weight);
}


02 out(write-only)

out 키워드를 사용하면, 함수가 값을 반환하는 방식으로 변수에 값을 할당할 수 있다. 호출한 쪽에서는 해당 변수의 초기화가 필요 없고 함수 내부에서는 반드시 값을 할당해야 한다. 즉 out은 함수가 여러 개의 값을 반환하거나 성공 여부와 함께 값을 넘겨줄 때 자주 사용된다. 대표적인 예로 int.TryParse()와 같은 메서드가 있다.

static void Pig(out int o)
{
    o = 100; // 메서드 내에서 초기화 필수
    Console.WriteLine(o);
}

public static void Main()
{
    int value; // 초기화 하지 않아도 된다
    Pig(out value);
}

만약 아래와 같이 메서드 내에서 초기화하지 않고 사용하면 컴파일 오류가 발생한다.

static void Pig(out int o)
{
    Console.WriteLine(o);
}

public static void Main()
{
    int value = 2;

    Pig(out value);
}

03 in (read only)

in 키워드는 읽기 전용 참조를 의미한다. 함수에 값을 복사하지 않고 참조로 넘기되, 함수 내부에서 해당 값을 수정할 수 없다. in 매개변수는 호출 전 반드시 초기화되어 있어야 하며 특히 구조체처럼 크기가 큰 데이터를 넘길 때 성능 최적화를 위해 사용된다. in은 값은 넘기되 수정은 막고 싶을 때 유용하다.

static void Pig(in int r)
{
    Console.WriteLine(r);
}

public static void Main()
{
    int value = 2;
    Pig(in value);
}

아래와 같이 변수를 수정하려고 하면 에러가 나온다.

static void Pig(in int r)
{
    r = 3;
    Console.WriteLine(r);
}

 

 

쉽게 비교해보면

ref : "이 종이에 이미 뭔가 적혀있어요. 필요하면 읽고 수정도 해줄게요." → 그래서 종이는 내용이 있어야 함

out : "이 종이는 빈 종이예요. 제가 처음부터 적어줄게요." → 초기 내용은 무의미

in : "이 종이에 뭐가 적혔는지 보기만 할게요." → 읽으려면 내용이 있어야함

 

반응형

댓글