The conditional operator ?: also known as the ternary conditional operator, evaluates a boolean expression and returns the result of one of the two expressions, depending on whether the boolean expression evaluates to true or false.
condition ? consequent : alternative
The condition expression must evaluate to true or false.
true, the consequent expression is evaluated, and its result becomes the result of the operation.false, the alternative expression is evaluated, and its result becomes the result of the operation.Before C# 7.2, the pattern of binding a ref variable to one or another expression conditionally was not expressible.
The typical workaround was to use a method as shown below.
ref T GetChoice(bool condition, ref T consequence, ref T alternative)
{
if (condition)
{
return ref consequence;
}
else
{
return ref alternative;
}
}
It is not an exact replacement of a ternary since all arguments must be evaluated at the call site. The following example will not work as you expect.
ref var result = ref GetChoice(arr != null, ref arr[0], ref otherArr[0]);
It will crash if arr[0] = null because arr[0] will be executed unconditionally.
Now in C# 7.2, you can use syntax like this.
<condition> ? ref <consequence> : ref <alternative>;
The above condition using GetChoice can be correctly written using ref ternary as shown below.
ref var result = ref (arr != null ? ref arr[0]: ref otherArr[0]);
In the case of a conditional ref expression, the type of consequent and alternative must be the same. Conditional ref expressions are not target-typed.
Let's consider the following example that shows how you can use it.
var array1 = new int[] { 21, 37, 19, 93, 5 };
var array2 = new int[] { 19, 17, 15, 13, 11, 9, 7, 5, 3, 1 };
int index = 3;
ref int refValue = ref index < 5 ? ref array1[index] : ref array2[index];
refValue = 100000;
index = 6;
refValue = ref index < 5 ? ref array1[index] : ref array2[index];
refValue = 100000;
Console.WriteLine(string.Join(" ", array1));
Console.WriteLine(string.Join(" ", array2));
Let's run the above example and, you will see the following output.
21 37 19 100000 5
19 17 15 13 11 9 100000 5 3 1
You can also use nested ternary by including a conditional ref expression as a second statement.
var array1 = new int[] { 21, 37, 19, 93, 5 };
var array2 = new int[] { 19, 17, 15, 13, 11, 9, 7, 5, 3, 1 };
int index = 3;
ref int refValue = ref index < 5 ? ref array1[index] : ref array2[index];
refValue = 100000;
index = 12;
refValue = ref index < 5 ? ref array1[index] : ref index < 10 ? ref array2[index] : ref array2[index - 10];
refValue = 100000;
Console.WriteLine(string.Join(" ", array1));
Console.WriteLine(string.Join(" ", array2));
Let's run the above example and, you will see the following output.
21 37 19 100000 5
19 17 100000 13 11 9 7 5 3 1