diff --git a/docs/csharp/language-reference/operators/conditional-operator.md b/docs/csharp/language-reference/operators/conditional-operator.md index 90bfa20595570..f43dfd87bc5f0 100644 --- a/docs/csharp/language-reference/operators/conditional-operator.md +++ b/docs/csharp/language-reference/operators/conditional-operator.md @@ -1,6 +1,6 @@ --- title: "?: Operator (C# Reference)" -ms.date: "07/20/2015" +ms.date: "11/20/2018" f1_keywords: - "?:_CSharpKeyword" - "?_CSharpKeyword" @@ -10,70 +10,76 @@ helpviewer_keywords: - "conditional operator (?:) [C#]" ms.assetid: e83a17f1-7500-48ba-8bee-2fbc4c847af4 --- - # ?: Operator (C# Reference) -The conditional operator (`?:`), commonly known as the ternary conditional operator, returns one of two values depending on the value of a Boolean expression. Following is the syntax for the conditional operator. +The conditional operator `?:`, commonly known as the ternary conditional operator, evaluates a Boolean expression, and returns the result of evaluating one of two expressions, depending on whether the Boolean expression evaluates to `true` or `false`. Beginning with C# 7.2, the [conditional ref expression](#conditional-ref-expression) returns the reference to the result of one of the two expressions. + +The syntax for the conditional operator is as follows: ```csharp -condition ? first_expression : second_expression; +condition ? consequence : alternative ``` -Beginning with C# 7.2, the `first_expression` and `second_expression` my be [`ref` expressions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/conditional-ref.md): +The `condition` expression must evaluate to `true` or `false`. If `condition` evaluates to `true`, the `consequence` expression is evaluated, and its result becomes the result of the operation. If `condition` evaluates to `false`, the `alternative` expression is evaluated, and its result becomes the result of the operation. Only `consequence` or `alternative` is evaluated. -```csharp -ref condition ? ref first_expression : ref second_expression; -``` +The type of `consequence` and `alternative` must be the same, or there must be an implicit conversion from one type to the other. -The result may be assigned to a `ref` or `ref readonly` variable, or to a variable with neither modifier. +The conditional operator is right-associative, that is, an expression of the form -## Remarks +```csharp +a ? b : c ? d : e +``` -The `condition` must evaluate to `true` or `false`. If `condition` is `true`, `first_expression` is evaluated and becomes the result. If `condition` is `false`, `second_expression` is evaluated and becomes the result. Only one of the two expressions is evaluated. This is particularly important for expressions where the result is a `ref`, as the following is valid: +is evaluated as ```csharp -ref (storage != null) ? ref storage[3] : ref defaultValue; +a ? b : (c ? d : e) ``` -The reference to `storage` is not evaluated when `storage` is null. +The following example demonstrates the usage of the conditional operator: + +[!code-csharp[non ref condtional](~/samples/snippets/csharp/language-reference/operators/ConditionalExamples.cs#ConditionalValue)] -When the result is a value, the type of `first_expression` and `second_expression` must be the same, or there must be an implicit conversion from one type to the other. When the result is a `ref`, the type of `first_expression` and `second_expression` must be the same. +## Conditional ref expression -You can express calculations that might otherwise require an `if-else` construction more concisely by using the conditional operator. For example, the following code uses first an `if` statement and then a conditional operator to classify an integer as positive or negative. +Beginning with C# 7.2, you can use the conditional ref expression to return the reference to the result of one of the two expressions. You can assign that reference to a [local ref](../keywords/ref.md#ref-locals) or [local ref readonly](../keywords/ref.md#ref-readonly-locals) variable, or use it as a [reference return value](../keywords/ref.md#reference-return-values) or as a [`ref` method parameter](../keywords/ref.md#passing-an-argument-by-reference). + +The syntax for the conditional ref expression is as follows: ```csharp -int input = Convert.ToInt32(Console.ReadLine()); -string classify; - -// if-else construction. -if (input > 0) - classify = "positive"; -else - classify = "negative"; - -// ?: conditional operator. -classify = (input > 0) ? "positive" : "negative"; +condition ? ref consequence : ref alternative ``` -The conditional operator is right-associative. The expression `a ? b : c ? d : e` is evaluated as `a ? b : (c ? d : e)`, not as `(a ? b : c) ? d : e`. - -The conditional operator cannot be overloaded. - -## Example +Like the original conditional operator, the conditional ref expression evaluates only one of the two expressions: either `consequence` or `alternative`. -The following example shows the conditional operator whose result is a value: +In the case of the conditional ref expression, the type of `consequence` and `alternative` must be the same. -[!code-csharp[csRefOperators?:](~/samples/snippets/csharp/language-reference/operators/ConditionalExamples.cs#ConditionalValue)] +The following example demonstrates the usage of the conditional ref expression: + +[!code-csharp[conditional ref](~/samples/snippets/csharp/language-reference/operators/ConditionalExamples.cs#ConditionalRef)] + +For more information, see the [feature proposal note](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/conditional-ref.md). + +## Conditional operator and an `if..else` statement + +Use of the conditional operator over an [if-else](../keywords/if-else.md) statement might result in more concise code in cases when you need conditionally to compute a value. The following example demonstrates two ways to classify an integer as negative or nonnegative: + +[!code-csharp[conditional and if-else](~/samples/snippets/csharp/language-reference/operators/ConditionalExamples.cs#CompareWithIf)] + +## Operator overloadability + +The conditional operator cannot be overloaded. -The following alternative shows the conditional operator where the result is a reference: +## C# language specification -[!code-csharp[csRefOperatorsRef?:](~/samples/snippets/csharp/language-reference/operators/ConditionalExamples.cs#ConditionalRef)] +For more information, see the [Conditional operator](~/_csharplang/spec/expressions.md#conditional-operator) section of the [C# language specification](../language-specification/index.md). -## See Also +## See also -- [C# Reference](../../../csharp/language-reference/index.md) -- [C# Programming Guide](../../../csharp/programming-guide/index.md) -- [C# Operators](../../../csharp/language-reference/operators/index.md) -- [if-else](../../../csharp/language-reference/keywords/if-else.md) -- [?. and ?[] Operators](../../../csharp/language-reference/operators/null-conditional-operators.md) -- [?? Operator](../../../csharp/language-reference/operators/null-coalescing-operator.md) +- [C# Reference](../index.md) +- [C# Programming Guide](../../programming-guide/index.md) +- [C# Operators](index.md) +- [if-else statement](../keywords/if-else.md) +- [?. and ?[] Operators](null-conditional-operators.md) +- [?? Operator](null-coalescing-operator.md) +- [ref keyword](../keywords/ref.md)