我正在与一个奇怪的,至少对我来说,重载.net的分辨率方法摔跤。我写了一个小样本来重现这个问题:
class Program
{
static void Main(string[] args)
{
var test = new OverloadTest();
test.Execute(0);
test.Execute(1);
Console.ReadLine();
}
}
public class OverloadTest
{
public void Execute(object value)
{
Console.WriteLine("object overload: {0}", value);
}
public void Execute(MyEnum value)
{
Console.WriteLine("enum overload: {0}", value);
}
}
public enum MyEnum
{
First = 1, Second = 2, Third = 3
}
将打印:
enum overload: 0
object overload: 1
基本上,调用的重载因值(0,1)而不是给定的数据类型而不同。
有人可以解释一下吗?
更新
我应该指出C#2和C#3之间存在不同的行为
Do((long)0) => object overload //C# 2
Do((long)0) => enum overload //C# 3
答案 0 :(得分:16)
是 - 常量0 隐式可转换为任何枚举类型。常量1仅显式可转换为枚举类型。两者都可以隐式转换为object
(通过装箱),但在可用的情况下,首选转换为枚举。
请注意, nothing 与枚举定义的值有关。任何非零值的转换都是显式的,无论它是否与枚举中的值匹配。它只是值0的特殊情况,这使得其他一些代码更简单(特别是在处理标志时)。我害怕找不到参考资料。
Bonus strangeness:由于MS编译器中的一个错误(永远不会被修复 - 它会破坏向后兼容性)它实际上是various zero constants,而不仅仅是一个整数。因此Execute(0d)
和Execute(0m)
也会将双精度和小数转换为枚举。它不适用于每个零常量 - 它取决于源代码的确切性质。这一切都很奇怪 - 按照Eric Lippert揭示所有内容的链接......
答案 1 :(得分:0)
我同意Jon Skeet的回答 - 请参阅1月11日17:32发表的帖子(上图)。 要进一步扩展,请参阅C#语言规范 - 第110页
6.1.3隐式枚举转化 隐式枚举转换允许将decimal-integer-literal 0转换为任何枚举类型以及其基础类型为枚举类型的任何nullable类型。在后一种情况下,通过转换为基础枚举类型并包装结果来评估转换(§4.1.10)。
仍有问题:
添加声明:
test.Execute(-0.0); //对象重载:0
添加以下内容:
test.Execute(+0.0); // enum overload:0
Jacques Colmenero 企业架构师 colmeneroj@videotron.ca
答案 2 :(得分:-1)
Enum刚刚映射到int(默认情况下)。 0不会映射到您的枚举,因此使用了对象的重载。 1映射到您的枚举,因此使用了Enum重载。
你可以这样做:
Execute((object) 1);
输出
对象重载:1