본문 바로가기

이것 저것 공부/C#

C# params, ref와 in, out 매개 변수 한정자

이 글은 C#에서 메서드 매개 변수를 선언할 때 사용할 수 있는 키워드들을 정리합니다.

  • params 는 이 매개 변수가 가변 개수의 인수를 사용할 수 있음을 지정합니다.
  • in 은 이 매개 변수를 참조로 전달할 수 있지만 호출된 메서드로만 읽을 수 있음을 지정합니다.
  • ref 는 이 매개 변수를 참조로 전달할 수 있고 호출된 메서드로 읽거나 쓸 수 있음을 지정합니다.
  • out 은 이 매개 변수가 참조로 전달되고 호출된 메서드에 의해 기록되도록 지정합니다.

params와 in, ref, out은 성질이 다르므로 두 분류로 나눠서 정리하겠습니다.


1.params

params 키워드를 사용하면 가변 개수의 인수를 사용하는 메서드 매개 변수를 지정할 수 있습니다.

메서드를 호출 할 때 지정된 형식의 인수 배열이나 지정된 형식의 쉼표로 구분된 인수 목록을 보낼 수 있습니다.

메서드를 선언 할 때, params 키워드로 선언된 매개 변수 뒤에는 매개 변수를 추가하는 것이 불가능하며 (따라서 params키워드는 마지막 매개 변수 1개에만 사용가능) , params매개 변수의 선언된 형식은 1차원 배열이어야 합니다.

 

예제

// 선언
public void UseParams(params int[] list){ // 1차원 배열의 형태로 선언
	
}

// 호출
void Main(){
    // 지정된 형식의 쉼표로 구분된 인수 목록으로 호출
    UseParams(1,2,3,4);
    
    // 지정된 형식의 인수 배열로 호출
    int[] paramsArray = {5,6,7,8,9};
    UseParams(paramsArray);
}

2. ref, in, out

ref, in ,out은 모두 매개 변수를 참조로 전달받는 키워드 입니다.
이중 in과 out은 매개 변수 한정자라고 불립니다.

메서드 내부에서 읽기 쓰기
ref 가능 가능
in 가능 불가능
out 가능 반드시 해야함

참조로 값이 전달 되기 때문에, 메서드 내부에서 값이 수정된다면, 참조되어 있는 변수의 값이 수정됩니다.

ref 또는 in 매개 변수로 전달하는 인수는 전달 전에 초기화 해야합니다.
out은 인수를 전달하기 전에 명시적으로 초기화할 필요가 없습니다.

위와 같은 조건 때문에, out 매개변수를 메서드 내부에서 사용하기 위해서는 매서드 내부에서 out 매개변수를 초기화 해야합니다.

in, ref, out은 오버로드 해결을 위한 메서드 시그니처의 일부로 간주되지 않습니다. 다음과 같은 오버로드는 불가능 합니다.

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

하지만 메서드 하나는 ref,in,out을 사용하고 다른 하나는 사용하지 않으면 오버로드를 할 수 있습니다.

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) => i = 5;
}

 

ref 키워드를 사용하여 다음과 같이 참조를 반환할 수 도 있습니다.

public class Book
{
    public string Author;
    public string Title;
}

public class BookCollection
{
    private Book[] books = { new Book { Title = "Call of the Wild, The", Author = "Jack London" },
                        new Book { Title = "Tale of Two Cities, A", Author = "Charles Dickens" }
                       };
    private Book nobook = null;

    public ref Book GetBookByTitle(string title)  // 참조를 반환하는 메서드
    {
        for (int ctr = 0; ctr < books.Length; ctr++)
        {
            if (title == books[ctr].Title)
                return ref books[ctr];
        }
        return ref nobook;
    }

    public void ListBooks()
    {
        foreach (var book in books)
        {
            Console.WriteLine($"{book.Title}, by {book.Author}");
        }
        Console.WriteLine();
    }
}

참조된 반환값을 받을 때에는 참조 지역변수를 사용해야합니다.

var bc = new BookCollection();
bc.ListBooks();

ref var book = ref bc.GetBookByTitle("Call of the Wild, The"); // 참조 지역 변수
if (book != null)
    book = new Book { Title = "Republic, The", Author = "Plato" };
bc.ListBooks();
// The example displays the following output:
//       Call of the Wild, The, by Jack London
//       Tale of Two Cities, A, by Charles Dickens
//       
//       Republic, The, by Plato
//       Tale of Two Cities, A, by Charles Dickens

ref var book 이 참조 지역 변수이며, 참조 지역 변수는 비참조 반환 값으로 초기화 할 수 없습니다.
즉 초기화의 오른쪽은 참초여야 합니다.

 

 

참조 : https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/method-parameters

 

메서드 매개 변수 - C# 참조

메서드 매개 변수(C# 참조)Method Parameters (C# Reference) 이 문서의 내용 --> in, ref 또는 out 없이 메서드에 대해 선언된 매개 변수는 값으로 호출된 메서드에 전달됩니다.Parameters declared for a method without in, ref or out, are passed to the called method by value. 메서드에서 해당 값을 변경할 수 있지만, 제어가 호출하는 프로시저로 다

docs.microsoft.com