C# out 키워드 완벽 정리
C#에서 out은 출력 전용 참조 매개변수를 만들 때 사용하는 키워드이다.
메서드 안에서 값을 만들어서, 메서드 밖으로 돌려보내고 싶을 때 사용한다.
1. out이란?
out은 메서드의 매개변수 앞에 붙여서 사용한다.
void GetNumber(out int number)
{
number = 10;
}
이 메서드는 number라는 값을 밖에서 받아오는 것이 아니라,
메서드 안에서 값을 넣어서 밖으로 내보내는 역할을 한다.
사용 예시는 다음과 같다.
int result;
GetNumber(out result);
Console.WriteLine(result);
출력 결과:
10
2. out의 핵심 특징
out의 가장 중요한 특징은 다음과 같다.
| 값을 밖으로 내보냄 | 메서드 안에서 만든 값을 호출한 쪽으로 전달 |
| 초기화하지 않아도 됨 | 호출 전에 변수에 값을 넣지 않아도 사용 가능 |
| 메서드 안에서 반드시 값 대입 | out 매개변수는 메서드가 끝나기 전에 반드시 값을 넣어야 함 |
| 여러 값을 반환할 때 유용 | 메서드는 기본적으로 하나만 return 가능하지만, out을 쓰면 여러 값 전달 가능 |
3. out은 왜 사용할까?
C#에서 메서드는 기본적으로 return으로 하나의 값만 반환할 수 있다.
int Add(int a, int b)
{
return a + b;
}
그런데 결과를 여러 개 돌려주고 싶을 때가 있다.
예를 들어, 이름과 나이를 동시에 구하고 싶다면 out을 사용할 수 있다.
void GetUserInfo(out string name, out int age)
{
name = "철수";
age = 17;
}
사용할 때는 이렇게 쓴다.
string userName;
int userAge;
GetUserInfo(out userName, out userAge);
Console.WriteLine(userName);
Console.WriteLine(userAge);
출력 결과:
철수
17
4. out 매개변수는 반드시 값을 넣어야 한다
out을 사용한 매개변수는 메서드 안에서 반드시 값을 대입해야 한다.
잘못된 코드:
void GetNumber(out int number)
{
// number에 값을 넣지 않음
}
이 코드는 컴파일 에러가 난다.
이유는 out 매개변수는 출력용 변수이기 때문에,
메서드가 끝날 때 반드시 값이 들어 있어야 하기 때문이다.
올바른 코드:
void GetNumber(out int number)
{
number = 10;
}
5. 호출 전에 변수를 초기화하지 않아도 된다
out은 메서드 안에서 값을 넣어줄 것이 확정되어 있기 때문에,
호출하기 전에 변수를 초기화하지 않아도 된다.
int value;
GetNumber(out value);
Console.WriteLine(value);
이 코드는 정상적으로 동작한다.
반면 일반 변수는 초기화하지 않고 사용하면 오류가 난다.
int value;
Console.WriteLine(value); // 오류
6. out 변수 선언을 한 줄로 줄이기
C#에서는 out 변수를 메서드 호출 부분에서 바로 선언할 수 있다.
GetNumber(out int value);
Console.WriteLine(value);
이렇게 하면 미리 변수를 따로 선언하지 않아도 된다.
즉, 아래 코드보다 더 간단하다.
int value;
GetNumber(out value);
7. TryParse와 out
out이 가장 많이 사용되는 대표적인 예시는 TryParse이다.
string input = "123";
bool success = int.TryParse(input, out int number);
Console.WriteLine(success);
Console.WriteLine(number);
출력 결과:
True
123
int.TryParse는 문자열을 숫자로 바꿀 수 있는지 검사한다.
| success | 변환에 성공했는지 여부 |
| number | 변환된 숫자 값 |
만약 변환에 실패하면 다음과 같다.
string input = "abc";
bool success = int.TryParse(input, out int number);
Console.WriteLine(success);
Console.WriteLine(number);
출력 결과:
False
0
"abc"는 숫자로 바꿀 수 없기 때문에 success는 false가 된다.
8. out과 return의 차이
return은 메서드의 결과를 직접 반환한다.
int GetNumber()
{
return 10;
}
out은 매개변수를 통해 값을 밖으로 내보낸다.
void GetNumber(out int number)
{
number = 10;
}
비교하면 다음과 같다.
| 역할 | 값을 반환 | 매개변수로 값을 내보냄 |
| 반환 개수 | 보통 1개 | 여러 개 가능 |
| 사용 위치 | 메서드의 반환형 | 매개변수 |
| 대표 용도 | 일반적인 결과 반환 | 여러 결과 반환, TryParse 패턴 |
9. out과 ref의 차이
out과 ref는 둘 다 참조 매개변수이다.
하지만 사용 목적이 다르다.
| 호출 전 초기화 | 필요 없음 | 반드시 필요 |
| 메서드 안 대입 | 반드시 해야 함 | 안 해도 됨 |
| 목적 | 값을 밖으로 출력 | 값을 받아서 수정 |
| 느낌 | 출력 전용 | 입력 + 출력 |
out 예시:
void SetValue(out int number)
{
number = 10;
}
호출할 때 초기화하지 않아도 된다.
int value;
SetValue(out value);
ref 예시:
void AddTen(ref int number)
{
number += 10;
}
호출 전에 반드시 값이 있어야 한다.
int value = 5;
AddTen(ref value);
Console.WriteLine(value);
출력 결과:
15
10. out은 출력 전용이다
out 매개변수는 메서드 안에서 기존 값을 읽기 위한 용도가 아니다.
메서드 안에서 새 값을 넣어 밖으로 보내는 용도이다.
예를 들어 다음 코드는 좋지 않다.
void Test(out int number)
{
Console.WriteLine(number); // 오류
number = 10;
}
number에 아직 값이 들어갔다고 보장할 수 없기 때문에,
값을 넣기 전에 읽을 수 없다.
올바른 코드는 다음과 같다.
void Test(out int number)
{
number = 10;
Console.WriteLine(number);
}
11. out을 여러 개 사용하는 예시
void Calculate(int a, int b, out int sum, out int difference)
{
sum = a + b;
difference = a - b;
}
사용 예시:
Calculate(10, 3, out int sum, out int difference);
Console.WriteLine(sum);
Console.WriteLine(difference);
출력 결과:
13
7
이처럼 out을 사용하면 메서드 하나에서 여러 결과를 받을 수 있다.
12. out을 무시하고 싶을 때
결과 값이 필요 없을 때는 _를 사용할 수 있다.
string input = "123";
bool success = int.TryParse(input, out _);
Console.WriteLine(success);
이 코드는 숫자로 변환 가능한지만 확인하고,
변환된 숫자 값은 사용하지 않는다.
13. out을 사용할 때 주의할 점
out은 편리하지만 너무 많이 쓰면 코드가 복잡해질 수 있다.
예를 들어 이런 코드는 읽기 어렵다.
void GetData(out int a, out int b, out int c, out int d, out int e)
{
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
}
out 매개변수가 너무 많으면 메서드의 역할이 불분명해진다.
이런 경우에는 클래스를 만들거나, 튜플을 사용하는 것이 더 좋을 수 있다.
(int sum, int difference) Calculate(int a, int b)
{
return (a + b, a - b);
}
사용 예시:
var result = Calculate(10, 3);
Console.WriteLine(result.sum);
Console.WriteLine(result.difference);
14. out을 사용하기 좋은 상황
out은 다음과 같은 상황에서 사용하기 좋다.
| 변환 성공 여부와 결과를 같이 받고 싶을 때 | int.TryParse |
| 여러 개의 결과를 반환하고 싶을 때 | 합, 차를 동시에 반환 |
| 메서드가 값을 만들어서 밖으로 넘겨야 할 때 | GetUserInfo(out name, out age) |
| 실패할 수도 있는 작업의 결과를 안전하게 받고 싶을 때 | TryGetValue |
15. Dictionary의 TryGetValue와 out
out은 Dictionary에서도 많이 사용된다.
Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("철수", 90);
bool found = scores.TryGetValue("철수", out int score);
Console.WriteLine(found);
Console.WriteLine(score);
출력 결과:
True
90
TryGetValue는 key가 존재하는지 확인하고,
존재하면 value를 out 매개변수에 넣어준다.
없는 key를 찾으면 다음과 같다.
bool found = scores.TryGetValue("영희", out int score);
Console.WriteLine(found);
Console.WriteLine(score);
출력 결과:
False
0
16. out의 장점
out의 장점은 다음과 같다.
| 여러 값을 반환 가능 | 메서드 하나에서 여러 결과를 받을 수 있음 |
| 초기화 부담이 적음 | 호출 전에 변수 값을 넣지 않아도 됨 |
| 실패 가능성이 있는 작업에 좋음 | TryParse, TryGetValue 같은 패턴에 적합 |
| 코드가 안전해짐 | 성공 여부와 결과 값을 함께 처리 가능 |
17. out의 단점
out의 단점도 있다.
| 너무 많이 쓰면 가독성 저하 | 매개변수가 많아지면 코드가 복잡해짐 |
| 메서드 호출이 길어짐 | out int a, out int b처럼 코드가 길어질 수 있음 |
| 반환 구조가 흩어짐 | 결과가 return이 아니라 매개변수 쪽에 나뉘어 있음 |
| 객체나 튜플이 더 나을 때도 있음 | 복잡한 데이터는 별도 타입으로 묶는 것이 좋음 |
18. 정리
out은 메서드 안에서 만든 값을 밖으로 내보내기 위한 출력 전용 참조 매개변수이다.
핵심은 다음과 같다.
| out | 값을 밖으로 내보내는 매개변수 |
| 초기화 | 호출 전에 초기화하지 않아도 됨 |
| 필수 대입 | 메서드 안에서 반드시 값을 넣어야 함 |
| 대표 예시 | int.TryParse, Dictionary.TryGetValue |
| ref와 차이 | ref는 입력과 출력, out은 출력 중심 |
즉, out은
메서드가 값을 만들어서 호출한 쪽에 전달해야 할 때 사용하는 키워드라고 정리할 수 있다.