三元运算符
根据布尔表达式的值返回两个值中的一个。
句法:
condition ? expression_if_true : expression_if_false;
例:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
三元运算符是右关联的,允许使用复合三元表达式。这是通过在父三元方程的真或假位置添加额外的三元方程来完成的。应注意确保可读性,但在某些情况下这可能是有用的速记。
在此示例中,复合三元运算评估 clamp
函数,如果它在范围内则返回当前值,如果低于范围则返回 min
值,如果高于范围则返回 max
值。
light.intensity = Clamp(light.intensity, minLight, maxLight);
public static float Clamp(float val, float min, float max)
{
return (val < min) ? min : (val > max) ? max : val;
}
三元运算符也可以嵌套,例如:
a ? b ? "a is true, b is true" : "a is true, b is false" : "a is false"
// This is evaluated from left to right and can be more easily seen with parenthesis:
a ? (b ? x : y) : z
// Where the result is x if a && b, y if a && !b, and z if !a
在编写复合三元语句时,通常使用括号或缩进来提高可读性。
expression_if_true 和 expression_if_false 的类型必须相同,或者必须存在从一个到另一个的隐式转换。
condition ? 3 : "Not three"; // Doesn't compile because `int` and `string` lack an implicit conversion.
condition ? 3.ToString() : "Not three"; // OK because both possible outputs are strings.
condition ? 3 : 3.5; // OK because there is an implicit conversion from `int` to `double`. The ternary operator will return a `double`.
condition ? 3.5 : 3; // OK because there is an implicit conversion from `int` to `double`. The ternary operator will return a `double`.
类型和转换要求也适用于你自己的类。
public class Car
{}
public class SportsCar : Car
{}
public class SUV : Car
{}
condition ? new SportsCar() : new Car(); // OK because there is an implicit conversion from `SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.
condition ? new Car() : new SportsCar(); // OK because there is an implicit conversion from `SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.
condition ? new SportsCar() : new SUV(); // Doesn't compile because there is no implicit conversion from `SportsCar` to SUV or `SUV` to `SportsCar`. The compiler is not smart enough to realize that both of them have an implicit conversion to `Car`.
condition ? new SportsCar() as Car : new SUV() as Car; // OK because both expressions evaluate to a reference of type `Car`. The ternary operator will return a reference of type `Car`.