Favicon

Method parameters

Peponi11/27/20246m

C#
SyntaxKeywordParameter

1. Introduction

C#의 형식에는 참조(class), 값(struct) 형식이 있으며 이를 메서드 매개 변수로 전달할 수 있다.

  • 참조 형식은 변수에 대한 참조의 복사본을 전달한다.
  • 값 형식은 변수의 복사본을 전달한다.

매개 변수를 선언할 때 사용 가능한 키워드는 아래와 같다.

  • params : 인수의 수가 가변인 것을 지정한다.
  • in : 매개 변수를 참조로 전달, 호출된 메서드에서 읽기 가능
  • ref : 매개 변수를 참조로 전달, 호출된 메서드에서 읽기 / 쓰기 가능
  • ref readonly : 매개 변수를 참조로 전달, 호출된 메서드에서 읽기 가능 (C# 12)
  • out : 매개 변수를 참조로 전달, 호출된 메서드에서 쓰기 가능

2. Example

class Foo
{
    public int Integer;
}
 
struct Bar
{
    public int Integer;
}
 
static void ChangeValue(Foo foo) => foo.Integer = 10;
static void ChangeValue(Bar bar) => bar.Integer = 10;
 
static void Main()
{
    Foo foo = new Foo() { Integer = 0 };
    ChangeValue(foo);   // 참조 전달
 
    Bar bar = new Bar() { Integer = 1 };
    ChangeValue(bar);   // 복사본 전달
 
    Console.WriteLine(foo.Integer);
    Console.WriteLine(bar.Integer);
}
 
/* output:
10
1
*/

3. 참조 형식 매개 변수

참조 형식을 메서드에 전달하는 경우 참조 (인스턴스의 주소) 에 대한 복사본을 전달한다.

  • 인스턴스의 주소를 통해 참조 멤버 액세스가 가능하다.
  • 호출된 메서드는 변수로 전달된 인스턴스의 주소를 변경할 수 없다.
  • ref 키워드를 통해 참조를 직접 전달할 수 있다.

3.1. Example

class Test
{
    public int X;
}
 
static void Foo(Test test)
{
    Console.WriteLine($"Foo start : {test.X}");
 
    // Change Member
 
    test.X = 100;
 
    Console.WriteLine($"Foo - X changed : {test.X}");
}
 
static void Bar(Test test)
{
    Console.WriteLine($"Bar start : {test.X}");
 
    // Change reference
 
    test = new() { X = 50 };
 
    Console.WriteLine($"Bar - test changed : {test.X}");
}
 
static void Main()
{
    Test t = new() { X = 1 };
 
    Foo(t);
 
    Console.WriteLine($"After Foo : {t.X}");
 
    Bar(t);
 
    Console.WriteLine($"After Bar : {t.X}");
}
 
/* output:
Foo start : 1
Foo - X changed : 100
After Foo : 100
Bar start : 100
Bar - test changed : 50
After Bar : 100
*/
ref keyword
class Test
{
    public int X;
}
 
static void Foo(ref Test test)
{
    Console.WriteLine($"Foo start : {test.X}");
 
    // Change Member
 
    test.X = 100;
 
    Console.WriteLine($"Foo - X changed : {test.X}");
}
 
static void Bar(ref Test test)
{
    Console.WriteLine($"Bar start : {test.X}");
 
    // Change reference
 
    test = new() { X = 50 };
 
    Console.WriteLine($"Bar - test changed : {test.X}");
}
 
static void Main()
{
    Test t = new() { X = 1 };
 
    Foo(ref t);
 
    Console.WriteLine($"After Foo : {t.X}");
 
    Bar(ref t);
 
    Console.WriteLine($"After Bar : {t.X}");
}
 
/* output:
Foo start : 1
Foo - X changed : 100
After Foo : 100
Bar start : 100
Bar - test changed : 50
After Bar : 50
*/

4. 값 형식 매개 변수

값 형식을 메서드에 전달하는 경우 값의 복사본을 전달한다.

  • 메서드는 구조체의 복사본을 전달받아 사용한다.
  • 인스턴스 및 모든 멤버가 복사되어 전달되기 때문에, 메서드에서는 원래 구조체에 접근이 불가능하다.
  • 참조 형식과 마찬가지로 ref 키워드를 통해 참조로 전달이 가능하다.

4.1. Example

struct Test
{
    public int X;
}
 
static void Foo(Test test)
{
    Console.WriteLine($"Foo start : {test.X}");
 
    // Change Member
 
    test.X = 100;
 
    Console.WriteLine($"Foo - X changed : {test.X}");
}
 
static void Bar(Test test)
{
    Console.WriteLine($"Bar start : {test.X}");
 
    // Change reference
 
    test = new() { X = 50 };
 
    Console.WriteLine($"Bar - test changed : {test.X}");
}
 
static void Main()
{
    Test t = new() { X = 1 };
 
    Foo(t);
 
    Console.WriteLine($"After Foo : {t.X}");
 
    Bar(t);
 
    Console.WriteLine($"After Bar : {t.X}");
}
 
/* output:
Foo start : 1
Foo - X changed : 100
After Foo : 1
Bar start : 1
Bar - test changed : 50
After Bar : 1
*/
ref keyword
struct Test
{
    public int X;
}
 
static void Foo(ref Test test)
{
    Console.WriteLine($"Foo start : {test.X}");
 
    // Change Member
 
    test.X = 100;
 
    Console.WriteLine($"Foo - X changed : {test.X}");
}
 
static void Bar(ref Test test)
{
    Console.WriteLine($"Bar start : {test.X}");
 
    // Change reference
 
    test = new() { X = 50 };
 
    Console.WriteLine($"Bar - test changed : {test.X}");
}
 
static void Main()
{
    Test t = new() { X = 1 };
 
    Foo(ref t);
 
    Console.WriteLine($"After Foo : {t.X}");
 
    Bar(ref t);
 
    Console.WriteLine($"After Bar : {t.X}");
}
 
/* output:
Foo start : 1
Foo - X changed : 100
After Foo : 100
Bar start : 100
Bar - test changed : 50
After Bar : 50
*/

5. 참조 자료