方法重载意外的行为 [英] Method overload resolution unexpected behavior

查看:132
本文介绍了方法重载意外的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我冥思苦想,一个奇怪的,至少对我来说,方法重载.NET的分辨率。我写了一个小样本重现该问题:

 类节目
{
    静态无效的主要(字串[] args)
    {
        VAR测试=新OverloadTest();
        test.Execute(0);
        test.Execute(1);

        到Console.ReadLine();
    }
}

公共类OverloadTest
{
    公共无效执行(对象的值)
    {
        Console.WriteLine(对象超载:{0},值);
    }

    公共无效执行(MyEnum值)
    {
        Console.WriteLine(枚举超载:{0},值);
    }
}

公共枚举MyEnum
{
    第一= 1,二= 2,第三= 3
}
 

将会打印:

 枚举过载:0
对象超负荷:1
 

基本上称为过载而不同的值(0,1)给定的数据类型,而不是

有人能解释一下吗?

更新

我应该指出,有与C#2和C#3

不同的行为

  DO((长)0)=>对象超负荷// C#2
DO((长)0)=>枚举超载// C#3
 

解决方案

是 - 恒0的隐含的转换为任何枚举类型。只有不断的1 明确的转换为枚举类型。两者都是隐式转换为对象(通过拳击),但转化为枚举是preferred它是可用的。

请注意,这具有的没有的做什么值的枚举定义。对于任何非零值转换是明确它是否匹配在枚举与否的值。它只是为0值,使C的简单(尤其是当与标志处理)其他$ C $的一个特例。我也没有这方面的规范,以找到参考,我害怕。

奖金陌生感:由于在MS编译器中的错误(永远是固定的 - 这将打破向后兼容),它实际上是<一个href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx">various零常量中,不只是一个整数。因此,执行(0D)执行(0米)将转换成一张双人床和一个十进制数来枚举了。它不适合工作的每次的零不变 - 这取决于源$ C ​​$ c中的确切性质。这一切都非常奇怪 - 按照链接,埃里克利珀显示所有...

I'm wrestling with a weird, at least for me, method overloading resolution of .net. I've written a small sample to reproduce the issue:

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
}

Will print:

enum overload: 0
object overload: 1

Basically the overload called is different depending on the value (0, 1) instead of the given data type.

Could someone explain?

Update

I should have pointed out that there's a different behaviour between C# 2 and C# 3

Do((long)0) => object overload //C# 2
Do((long)0) => enum overload   //C# 3 

解决方案

Yes - the constant 0 is implicitly convertible to any enum type. The constant 1 is only explicitly convertible to the enum type. Both are implicitly convertible to object (via boxing) but the conversion to the enum is preferred where it's available.

Note that this has nothing to do with what values the enum defines. The conversion for any non-zero value is explicit whether it matches a value in the enum or not. It's just a special case for the value 0, which makes some other code simpler (particularly when dealing with flags). I don't have the spec on hand to find the reference, I'm afraid.

Bonus strangeness: due to a bug in the MS compiler (never to be fixed - it would break backward compatibility) it's actually various zero constants, not just an integer. So Execute(0d) and Execute(0m) will convert a double and a decimal to the enum too. It doesn't work for every zero constant - it depends on the exact nature of the source code. It's all very odd - follow the link where Eric Lippert reveals all...

这篇关于方法重载意外的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆