:
가 붙은 것을 처음 봤다. 조사해보니 Named 파라미터라더라. 그 내용을 정리하고자 한다.클래스가 갖는 기능, 혹은 객체와 관련된 함수를 메소드라고 한다.
메소드는 N개의 인수(매개변수, 파라미터)를 가질 수 있으며, 하나의 반환 값을 갖는다. 또한 public
이나 private
같은 접근 제한자를 반환 값 앞에 둘 수 있다.
public int Method(inta, string b, bool c)
{
}
C#은 메소드에 파라미터를 전달할 때, 값을 복사하여 전달하는 Call by Value
방식을 사용한다.
즉, 전달 받은 값을 메소드 내에서 변경해도 전달되었던 인수의 값은 변하지 않는다.
class Calculator
{
static void Swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
static void Main(string[] args)
{
int x = 3;
int y = 5;
Swap(x, y);
Console.WriteLine($"x = {x}"); // x = 3
Console.WriteLine($"y = {y}"); // y = 5
}
}
메소드에 파라미터를 전달할 때, 참조 형식으로 전달하고자 하면 C#에서는 ref
키워드를 사용한다.
이는 변수의 포인터 값을 전달하는 것으로, 메소드 내에서 값을 변경하면 메소드 외부에도 적용된다.
ref
를 사용하기 위해서는 ref
로 전달되는 변수가 사전에 초기화되어 있어야 한다.
그외에도 Call by Reference
를 사용하기 위한 out
, in
등의 매개 변수 한정자가 있다.
C#에서 간접 참조에 좀 더 높은 가독성을 주기 위해 제공하는 것.
가독성을 준다는 것은, 이러한 한정자로 간접 참조의 목적을 알기 쉽게 한다는 것을 의미한다.
ref / in / out 이 있다.
ref
참조로 전달되는 인자를 의미한다.
참조를 목적으로 한다.
ref 한정자를 쓰면 인자가 반드시 초기화 되어 있어야 한다.
호출할 때 꼭 ref 키워드를 적어야 한다.
예시 코드
// C++
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
// C#
// ref 한정자를 쓰면 인자가 반드시 초기화 되어 있어야 한다.
// 초기화를 하지 않으면 컴파일 오류가 난다.
void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
int a = 10;
int b = 20;
Swap(ref a, ref b); // 호출할 때 꼭 ref 키워드를 적는다.
in
참조로 전달되나, 변경이 되지 않는 인자를 의미한다.
입력을 목적으로 한다.
in 한정자도 인자가 반드시 초기화 되어야 한다.
호출할 때는 적어주지 않아도 된다.
예시 코드
// C++
void Foo(const int& a, const int& b)
{
// Do Something...
}
// C#
// in 한정자도 인자가 반드시 초기화 되어야 한다.
// 초기화를 하지 않으면 컴파일 오류가 난다.
void Foo(in int a, in int b)
{
// Do Something...
}
out
참조로 전달되는 인자이며, 매개변수를 이용한 출력을 의미한다.
출력을 목적으로 한다.
out 한정자는 함수가 끝나기 전 반드시 어떤 값이 할당되어야 한다.
호출할 때 꼭 out 키워드를 적어야 한다.
예시 코드
// C++
void Foo(int a, int b, int& result)
{
result = a + b;
}
// C#
// out 한정자는 함수가 끝나기 전 반드시 어떤 값이 할당되어야 한다.
void Foo(int a, int b, out int result)
{
result = a + b;
}
int r;
Foo(10, 20, out r); // 호출할 땐 꼭 out 키워드를 적는다.
메소드에 파라미터를 전달할 때, 일반적으로는 파라미터의 순서에 따라 파라미터가 넘겨졌다.
Named 파라미터를 사용하면 인수를 매개 변수 목록 내의 해당 위치가 아닌 해당 이름과 일치시켜 매개 변수에 대한 인수를 지정할 수 있다.
Method(name: "John", age: 10, score: 90);
class Calculator
{
static void Swap(in int a, in int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
int x = 3;
int y = 5;
Swap(x, y); // 일반적으로는 이렇게 호출한다.
Swap(b: x, a: y);
// 이렇게 파라미터의 이름을 알면 순서 상관없이 전달할 수 있다.
Console.WriteLine($"x = {x}"); // x = 3
Console.WriteLine($"y = {y}"); // y = 5
}
}
메소드의 파라미터가 기본 값을 가지고 있으면, 그 파라미터를 Optional 파라미터라고 한다.
int Calc(int a, int b, string calcType = "+")
{
}
Optional 파라미터를 사용하면 메소드를 호출할 때 해당 인수를 생략할 수 있다.
Optional 파라미터는 반드시 파라미터들 중 마지막에 있어야 하며, 여러 개의 Optional 파라미터가 있을 경우에는 Optional이 아닌 파라미터들 뒤에 위치해야 한다.
class Calculator
{
int Calc(int a, int b, string calcType = "+")
{
switch (calcType)
{
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
return a / b;
default:
throw new ArithmeticException();
}
}
static void Main(string[] args)
{
Calculator c = new Calculator();
int ret = c.Calc(1, 2);
Console.WriteLine($"ret = {ret}"); // ret = 3
ret = c.Calc(1, 2, "*");
Console.WriteLine($"ret = {ret}"); // ret = 2
}
}
일반적으로 메소드의 파라미터 개수는 정의와 함께 고정된다.
다만 파라미터의 개수를 미리 알 수 없는 경우, params
키워드를 사용해 가변 배열을 인수로 갖게 할 수 있다.
반드시 파라미터 중 하나만 존재해야 하며, 파라미터 중 마지막에 위치해야 한다.
int Calc(params int[] values){};
int s = Calc(1, 2, 3, 4);
s = Calc(6, 7, 8, 9, 10);