?: 연산자(삼항 조건 연산자)
?: 연산자(삼항 조건 연산자)
조건 연산자 ?:(삼항 조건 연산자라고도 해요)는 불리언(Boolean) 식을 평가한 다음, 그 결과가 true인지 false인지에 따라 두 식 중 하나의 결과를 돌려줘요. 바로 아래 예시를 볼게요.
string GetWeatherDisplay(double tempInCelsius) => tempInCelsius < 20.0 ? "Cold." : "Perfect!";
Console.WriteLine(GetWeatherDisplay(15)); // output: Cold.
Console.WriteLine(GetWeatherDisplay(27)); // output: Perfect!
본문
위 예시에서 보이는 것처럼 조건 연산자의 문법은 다음과 같아요.
condition ? consequent : alternative
condition 식은 반드시 true 또는 false로 평가돼야 해요. condition이 true로 평가되면 consequent 식이 평가되고 그 결과가 연산의 결과가 돼요. condition이 false로 평가되면 alternative 식이 평가되고 그 결과가 연산의 결과가 되죠. 여기서 중요한 점은 consequent와 alternative 중 하나만 평가된다는 거예요.
조건식은 대상 형식에 맞춰지는(target-typed) 성질이 있어요. 즉 조건식의 대상 형식을 알고 있다면 consequent와 alternative의 형식이 모두 그 대상 형식으로 암시적으로 변환될 수 있어야 한다는 뜻이에요. 예시를 보면 바로 이해돼요.
var rand = new Random();
var condition = rand.NextDouble() > 0.5;
int? x = condition ? 12 : null;
IEnumerable<int> xs = x is null ? new List<int>() { 0, 1 } : new int[] { 2, 3 };
반대로 조건식의 대상 형식을 모를 때는(예를 들어 var 키워드를 쓸 때) consequent와 alternative의 형식이 같아야 하거나, 한쪽 형식에서 다른 쪽 형식으로의 암시적 변환이 존재해야 해요.
var rand = new Random();
var condition = rand.NextDouble() > 0.5;
var x = condition ? 12 : (int?)null;
조건 연산자는 오른쪽 결합(right-associative)이에요. 다시 말해
a ? b : c ? d : e
형태의 식은 다음과 같이 평가돼요.
a ? b : (c ? d : e)
[!TIP] 조건 연산자가 어떻게 평가되는지 기억하는 데 쓸 수 있는 암기법이 하나 있어요.
is this condition true ? yes : no
조건 ref 식
조건 ref 식(conditional ref expression)은 조건에 따라 변수 참조를 돌려줘요. 아래 예시를 볼게요.
int[] smallArray = {1, 2, 3, 4, 5};
int[] largeArray = {10, 20, 30, 40, 50};
int index = 7;
ref int refValue = ref ((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]);
refValue = 0;
index = 2;
((index < 5) ? ref smallArray[index] : ref largeArray[index - 5]) = 100;
Console.WriteLine(string.Join(" ", smallArray));
Console.WriteLine(string.Join(" ", largeArray));
// Output:
// 1 2 100 4 5
// 10 20 0 40 50
조건 ref 식의 결과는 ref 대입에 쓸 수 있어요. 참조 반환으로 사용하거나, ref, out, in, ref readonly 메서드 매개 변수로 넘길 수 있죠. 위 예시에서 보이는 것처럼 조건 ref 식의 결과에 값을 대입할 수도 있어요.
조건 ref 식의 문법은 다음과 같아요.
condition ? ref consequent : ref alternative
조건 연산자와 마찬가지로 조건 ref 식도 두 식 중 하나, 즉 consequent 또는 alternative만 평가해요.
조건 ref 식에서는 consequent와 alternative의 형식이 같아야 해요. 조건 ref 식은 대상 형식에 맞춰지지 않아요.
조건 연산자와 if 문
값을 조건에 따라 계산해야 할 때 if 문 대신 조건 연산자를 쓰면 코드가 더 간결해질 수 있어요. 다음 예시는 정수를 음수/음수가 아닌 수로 분류하는 두 가지 방법을 보여줘요.
int input = new Random().Next(-5, 5);
string classify;
if (input >= 0)
{
classify = "nonnegative";
}
else
{
classify = "negative";
}
classify = (input >= 0) ? "nonnegative" : "negative";
연산자 오버로드 가능 여부
사용자 정의 형식은 조건 연산자를 오버로드할 수 없어요.
C# 언어 사양
자세한 내용은 C# 언어 사양의 Conditional operator 섹션을 참고하세요.
더 새로운 기능에 대한 사양은 다음과 같아요.