【问题标题】:C# Enum requires cast in ternary? [duplicate]C# Enum 需要三进制转换? [复制]
【发布时间】:2017-02-07 10:10:04
【问题描述】:

今天我在Codegolf StackExchange 进行了另一个 Codegolf 挑战,我尝试这样做:

SomeEnum = SomeCondition ? 1 : 2;

但这告诉我Cannot convert source type 'int' to target type 'SomeEnum',所以我尝试了这个:

SomeEnum = SomeCondition ? (SomeEnum)1 : (SomeEnum)2;

然后解决了我的问题,但令我惊讶的是,这里的第一个演员据说是多余的。我的问题是:为什么我只需要将最后一个整数转换为 SomeEnum

【问题讨论】:

  • 如果去掉“冗余”转换,代码实际上还能编译吗?
  • 你有这方面的一个小例子吗?我试图复制它,我必须同时转换两个结果,否则我的代码将无法编译。
  • @Damien_The_Unbeliever 是的,当您只投射一侧时,代码仍然可以编译并且工作正常。看起来很混乱!
  • 不应该,根据 C# 规范。您可以尝试创建一个minimal reproducible example 吗?
  • 您的高尔夫代码有一个重要的区别 - 第一个文字是文字 0 而不是 1

标签: c# enums casting ternary


【解决方案1】:

条件运算符的规则是(C# Spec 7.14):

•   If x has type X and y has type Y then
o   If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
o   If an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
o   Otherwise, no expression type can be determined, and a compile-time error occurs.

一般来说,枚举和整数之间没有任何方向的隐式转换。

那么,为什么您的代码有效?因为在您的实际代码中,第一个值是0,而不是1。因此,我们得到了一种可以将整数隐式转换为枚举的情况(C# Spec 6.1.3):

隐式枚举转换允许将 decimal-integer-literal 0 转换为任何 enum-type 和任何 nullable-type其基础类型是 枚举类型...

【讨论】:

  • 非常感谢您的回答,我从来不知道这一点,也不知道 0 会对我的示例产生影响。我现在知道了! :)
  • 这个故事的寓意是不要发布伪代码,发布一个minimal, complete and verifiable示例;-)
  • @Equalsk 是的,这肯定会避免这里出现一堆混乱。我会记住的!
【解决方案2】:

你也可以这样写

SomeEnum = (SomeEnum)(SomeCondition ? 1 : 2);

左侧的SomeEnum 总是期望结果为'SomeEnum'。所以我们需要转换它。

【讨论】:

  • 这实际上是一种不混淆的投射方式,我肯定会使用它并且我赞成你的答案,但它并没有真正完全回答我的问题!无论如何谢谢:)
【解决方案3】:

要将三元运算符的结果绑定到SomeEnum,两个分支的结果(true和false)应该能够隐式转换SomeEnum,但是有没有隐式转换运算符默认为int 为c# 中的enum 类型定义。如果有隐式运算符,这将是有效的场景。

我希望这能解释这种情况。

【讨论】:

  • 条件运算符的返回类型仅基于它所包含的表达式的类型。正如你所说,它并不依赖于结果变量(事实上,在很多情况下,当用作更大表达式的一部分时,不存在“结果变量”)
  • 感谢更正,我已经编辑了我的答案。
【解决方案4】:

编译时没有任何警告:

SomeEnum SomeEnum = (true) ? (SomeEnum)1 : (SomeEnum)2;

但是你应该给枚举变量赋一个枚举值:

SomeEnum SomeEnum = (true) ? SomeEnum.First : SomeEnum.Second;

public enum SomeEnum : byte
{
    First = 1,
    Second = 2
}

以下内容应该编译:

SomeEnum SomeEnum = (true) ? (SomeEnum)1 : 2; //THIS WON'T COMPILE!

...除非第一个值为0:

SomeEnum SomeEnum = (true) ? 0 : 2;

【讨论】:

  • 看看my code here,它编译得很好,而它似乎与你所说的不应该编译的几乎相同。我很困惑。
  • 几乎相同不等于相同。不同之处在于您最初发布的代码将值设置为 1 而不是 0。其他答案指出的差异很大。当您提出问题时,您应该始终提供可重现的问题样本,这是有原因的......
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 2018-10-14
  • 2021-03-19
  • 1970-01-01
  • 2011-03-24
  • 2011-09-15
相关资源
最近更新 更多