重载子类中的方法(Enum vs int)

时间:2012-07-17 04:25:04

标签: c# overloading derived-class

为什么以下两个代码示例会产生不同的输出?

案例1

enum EnumType
{
    First,
    Second,
    Third
}

class ClassB
{
    public string Func(int index)
    {
        return "Func(int)";
    }

    public string Func(EnumType type)
    {
        return "Func(EnumType)";
    }
}

class Program
{
    static void Main(string[] args)
    {
        ClassB b = new ClassB();
        Console.WriteLine(b.Func(0));
        Console.WriteLine(b.Func(EnumType.First));
        Console.ReadLine();
    }
}

输出:

Func(int)
Func(EnumType)

案例2

enum EnumType
{
    First,
    Second,
    Third
}

class ClassA
{
    public string Func(int index)
    {
        return "Func(int)";
    }
}

class ClassB : ClassA
{
    public string Func(EnumType enumType)
    {
        return "Func(EnumType)";
    }
}

class Program
{
    static void Main(string[] args)
    {
        ClassB b = new ClassB();
        Console.WriteLine(b.Func(0));
        Console.WriteLine(b.Func(EnumType.First));
        Console.ReadLine();
    }
}

输出:

Func(EnumType)
Func(EnumType)

我很困惑。这是否意味着Func(EnumType)隐藏了在基数中声明的Func(int)?如果是这种情况,那么为什么文字0 在第二种情况下隐式地转换为EnumType而没有警告?

修改

当我尝试

时,有更多有趣的行为
Console.WriteLine(b.Func(0));         
Console.WriteLine(b.Func(1));
Console.WriteLine(b.Func(EnumType.First));

你猜测输出应该是什么样的?

这里是:

 Func(EnumType)
 Func(int)
 Func(EnumType)

为什么0和1的理由被区别对待?

编辑2:

事实证明,文字0确实在C#中具有特殊意义。

Herehere我找到了对此行为的精彩描述(请参阅已接受的答案)。

2 个答案:

答案 0 :(得分:5)

是的,它确实隐藏了A类中声明的Func(int)。

此外,请参阅enum (C# Reference)

  

枚举元素的默认基础类型是int

您可能还想查看Polymorphism (C# Programming Guide)

修改

如果你想改变

Console.WriteLine(b.Func(0));          
Console.WriteLine(b.Func(1)); 
Console.WriteLine(b.Func(EnumType.First)); 

int i = 0;
Console.WriteLine(b.Func(i));          
Console.WriteLine(b.Func(1)); 
Console.WriteLine(b.Func(EnumType.First)); 

你会发现输出应该是

Func(int)   
Func(int)   
Func(EnumType)

如果直接传递给函数调用,似乎0被隐式地转换为默认的枚举值。

编辑2

我检查了IL代码,似乎它隐式地将0转换为枚举

IL_0000: nop
IL_0001: newobj instance void ClassB::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.0
IL_0009: callvirt instance string ClassB::Func(valuetype EnumType)
IL_000e: call void [mscorlib]System.Console::WriteLine(string)
IL_0013: nop
IL_0014: ldloc.0
IL_0015: ldc.i4.0
IL_0016: callvirt instance string ClassB::Func(valuetype EnumType)
IL_001b: call void [mscorlib]System.Console::WriteLine(string)
IL_0020: nop
IL_0021: call string [mscorlib]System.Console::ReadLine()
IL_0026: pop
IL_0027: ret

答案 1 :(得分:0)

枚举的基础类型是int,因此ClassB函数会隐藏ClassA版本。

尝试将其更改为:

enum EnumType : byte
{
    First,
    Second,
    Third
}
...
Console.WriteLine(b.Func(256));  // out of range for a byte

你应该看到它调用int函数。