?: 연산자(삼항 조건 연산자)

?: 연산자(삼항 조건 연산자)

조건 연산자 ?:(삼항 조건 연산자라고도 해요)는 불리언(Boolean) 식을 평가한 다음, 그 결과가 true인지 false인지에 따라 두 식 중 하나의 결과를 돌려줘요. 바로 아래 예시를 볼게요.

출처: ?: operator - the ternary conditional operator

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로 평가돼야 해요. conditiontrue로 평가되면 consequent 식이 평가되고 그 결과가 연산의 결과가 돼요. conditionfalse로 평가되면 alternative 식이 평가되고 그 결과가 연산의 결과가 되죠. 여기서 중요한 점은 consequentalternative 중 하나만 평가된다는 거예요.

조건식은 대상 형식에 맞춰지는(target-typed) 성질이 있어요. 즉 조건식의 대상 형식을 알고 있다면 consequentalternative의 형식이 모두 그 대상 형식으로 암시적으로 변환될 수 있어야 한다는 뜻이에요. 예시를 보면 바로 이해돼요.

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 키워드를 쓸 때) consequentalternative의 형식이 같아야 하거나, 한쪽 형식에서 다른 쪽 형식으로의 암시적 변환이 존재해야 해요.

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 식에서는 consequentalternative의 형식이 같아야 해요. 조건 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 섹션을 참고하세요.

더 새로운 기능에 대한 사양은 다음과 같아요.

더 알아보기