2012-07-17 25 views
6

Tại sao hai mẫu mã sau tạo ra đầu ra khác nhau?Quá tải một phương thức trong phân lớp (Enum vs int)

Trường hợp 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(); 
    } 
} 

Output:

Func(int) 
Func(EnumType) 

Trường hợp 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(); 
    } 
} 

Output:

012.351.
Func(EnumType) 
Func(EnumType) 

Tôi đang bối rối. Nó có nghĩa là Func (EnumType) ẩn Func (int) được khai báo trong cơ sở? Nếu đây là trường hợp thì tại sao chữ 0 là ngầm được được truyền tới EnumType trong trường hợp thứ hai mà không có cảnh báo?

EDIT:

Thậm chí còn có hành vi thú vị hơn khi tôi cố gắng

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

đoán của bạn là gì đầu ra nên xem xét như thế nào?

ở đây là:

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

Bất cứ ý tưởng tại sao 0 và 1 được điều trị khác nhau?

EDIT 2:

Nó chỉ ra rằng đen 0 thực sự có ý nghĩa đặc biệt trong C#.

Herehere Tôi đã tìm thấy mô tả tuyệt vời về hành vi này (xem câu trả lời được chấp nhận).

Trả lời

5

Có, nó ẩn Func (int) được khai báo trong lớp A.

Hơn nữa, vui lòng xem enum (C# Reference)

Giá trị mặc định loại tiềm ẩn các yếu tố liệt kê là int

Bạn cũng có thể muốn có một cái nhìn tại Polymorphism (C# Programming Guide)

EDIT

Nếu bạn muốn thay đổi

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)); 

bạn sẽ thấy rằng sản lượng nên được

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

Dường như là 0 được ngầm đúc với giá trị enum mặc định nếu chuyển trực tiếp đến các cuộc gọi chức năng .

EDIT 2

Tôi đã kiểm tra mã IL và nó dường như rằng nó ngầm phôi các từ 0 đến một enum

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 
+0

tại sao không có cảnh báo về sự chuyển đổi tiềm ẩn từ int (0) sang EnumType? – alexm

+0

Bạn có thể muốn đọc thêm một số chi tiết về các hội tụ ngầm http://msdn.microsoft.com/en-us/library/aa691280(v=vs.71) –

+0

@atander: vẫn còn sự khác biệt "huyền diệu" giữa 0 và 1 (xem câu hỏi đã chỉnh sửa của tôi). Có tài liệu ở đâu đó không? – alexm

0

Các loại cơ bản thuộc kiểu liệt kê là int, vì vậy chức năng ClassB ẩn phiên bản ClassA.

Cố gắng thay đổi nó như thế này:

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

Bạn sẽ thấy nó gọi hàm int để thay thế.