出于好奇:为什么我可以将0.0分配给枚举类型的变量,而不是1.0?看看下面的代码:
public enum Foo
{
Bar,
Baz
}
class Program
{
static void Main()
{
Foo value1 = 0.0;
Foo value2 = 1.0; // This line does not compile
Foo value3 = 4.2; // This line does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
我认为数字类型和枚举值之间的转换只允许通过强制转换?那就是我可以编写Foo value2 = (Foo) 1.0;
以便第2行Main
可以编译.为什么0.0
C#中的值有例外?
Eri*_*ert 97
乔恩的回答是正确的.我会补充以下几点.
我造成了这个愚蠢而令人尴尬的错误.很多道歉.
这个错误是由于我误解了编译器中"表达式为零"谓词的语义而引起的; 我相信它只检查整数零相等,实际上它正在检查更多的"这是这种类型的默认值吗?" 事实上,在早期版本的bug中,实际上可以将任何类型的默认值分配给枚举!它现在只是数字的默认值.(课程:仔细命名助手谓词.)
我试图实现的行为,我搞砸了实际上是一个稍微不同的bug的解决方法.你可以在这里阅读整个可怕的故事:http://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx和这里http: //blogs.msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx(教训:在修复旧版时很容易引入新的更糟糕的错误那些.)
C#团队决定将这种错误行为归咎于而不是修复它,因为破坏现有代码而没有引人注目的好处的风险太高了.(课程:第一次就把它弄好!)
我在Roslyn中编写的用于保存此行为的代码可以在方法HasImplicitEnumerationConversion
中找到compilers\csharp\source\binder\semantics\conversions\conversions.cs
- 请参阅它以获取有关Roslyn行为的更多详细信息.(请注意,我把命名谓词以及对心脏的教训- HasImplicitEnumerationConversion
,IsNumericType
以及IsConstantNumericZero
所有不正是他们说在锡我在转换目录中写道:几乎所有的代码,我鼓励你阅读这一切因为有.关于C#如何与评论中的规范不同的许多有趣的事实.我使用SPEC VIOLATION进行装饰,以便于查找.)
还有一个兴趣点:C#还允许在枚举初始值设定项中使用任何枚举值,无论其是否为zeroness:
enum E { A = 1 }
enum F { B = E.A } // ???
Run Code Online (Sandbox Code Playgroud)
关于这是否合法,规范有些模糊,但同样,由于这已经在编译器中存在了很长时间,新的编译器可能会保持这种行为.
Jon*_*eet 94
这是一个你可以使用0.0的bug.编译器隐式将所有值为零的常量表达式视为0.
现在,根据C#5规范的6.1.3节,编译器允许从常量表达式0到枚举的隐式转换是正确的int
:
隐式枚举转换允许将decimal-integer-literal 0转换为任何枚举类型和任何可以为其类型为枚举类型的可空类型.在后一种情况下,通过转换为基础枚举类型并包装结果来评估转换(第4.1.10节).
我以前曾与C#团队讨论过这个问题:他们希望将意外转换从0.0(实际上是0.0m和0.0f)移除到枚举值,但不幸的是我收集了它破坏了太多的代码 - 尽管它应该永远不会被允许.
Mono的mcs
编译器禁止所有这些浮点转换,尽管它确实允许:
const int Zero = 0;
...
SomeEnum x = Zero;
Run Code Online (Sandbox Code Playgroud)
尽管事实Zero
是一个常量表达式但不是十进制整数字面值.
我不会惊讶地看到C#规范将来会改变以允许任何值为0的整数常量表达式(即模仿mcs
),但我不希望浮点转换正式变得正确.(关于预测C#的未来,我当然错了,当然......)
Kon*_*lph 10
C#中的枚举按定义为整数值.为了保持一致性,C#不应该接受这些赋值中的任何一个,而是0.0
静默地视为整数0
.这可能是来自C的保留,其中文字0
被特别处理并且基本上可以采用任何给定类型 - 整数,浮点数,空指针......你可以命名它.
归档时间: |
|
查看次数: |
4356 次 |
最近记录: |