2010-08-16 33 views
9

Các quy tắc liên quan đến chức năng Quá tải là gì?C# quy tắc quá tải chức năng

Tôi có đoạn mã sau:

public T genericFunc<T>() where T : Component, new() 
{ 
    T result = new T(); 
    overloadedFunction(result); 
} 

private overloadedFunction (Component c) // catch all function 

private overloadedFunction (DerivedFromComponent dfc) // specific function 

khi tôi gọi mã trên với:

genericFunc<DerivedFromComponent>(); 

tôi hy vọng các overloadedFunction cụ thể hơn để được gọi, tuy nhiên bắt tất cả các hàm được gọi thay vì , tại sao thế này ?. Khi bước qua đoạn mã trên, kiểu T thực sự là DerivedFromComponent, tôi nghĩ rằng CLR đã chọn kết quả phù hợp nhất có thể khi chạy!

Trả lời

14

Trình biên dịch thực hiện độ phân giải quá tải trong phạm vi genericFunckhi phương pháp đó được biên dịch. Tại thời điểm đó, nó không biết đối số kiểu bạn sẽ cung cấp, vì vậy nó chỉ biết rằng nó có thể gọi là đầu tiên của quá tải của bạn.

Ví dụ của bạn sử dụng generics làm cho cuộc sống phức tạp hơn, nhưng quá tải là luôn luôn được giải quyết lúc biên dịch (giả sử bạn không sử dụng dynamic).

Một ví dụ đơn giản không sử dụng Generics:

void Foo(string text) { } 
void Foo(object o) {} 
... 
object x = "this is a string"; 
Foo(x); 

sẽ gọi quá tải thứ hai, bởi vì thời gian biên dịch loại x chỉ là phản đối.

Để biết thêm về điều này, hãy đọc article on overloading gần đây của tôi.

3

Jon Skeet phù hợp với thực tế là độ phân giải quá tải được xác định tại thời gian biên dịch. Tôi nghĩ tôi sẽ thêm một câu trả lời khác không phải là câu hỏi của bạn nhưng thú vị để lưu ý.

Trong C# 4, từ khóa động có thể được sử dụng để hoãn độ phân giải quá tải cho đến khi chạy. Hãy xem xét các đoạn sau đó in:

Base! 
Derived! 


class Base { 
} 

class Derived : Base { 
} 

void DoSomething(Base x) { 
    Console.WriteLine("Base!"); 
} 

void DoSomething(Derived x) { 
    Console.WriteLine("Derived!"); 
} 

void DoSomething<T>() where T: Base, new() { 
    dynamic x = new T(); 
    DoSomething(x); 
} 

void Main() 
{ 
    DoSomething<Base>(); 
    DoSomething<Derived>(); 
} 
+0

Doh, và trong thời gian nó đã cho tôi để viết Jon Skeet này cũng ghi nhận động. – Josh

+0

Nếu chỉ có tôi có thể có được quản lý để mùa xuân cho một bản sao mới sáng bóng của VS2010 tất cả các rắc rối của tôi sẽ bốc hơi ... nhưng than ôi tôi bị mắc kẹt với NET 3.5 và VS2008. –

+2

Thành thật mà nói, tôi sẽ không khuyên bạn sử dụng mã trên để giải quyết vấn đề. Nó không phải là một ví dụ rất tốt về việc sử dụng hợp lý cho độ phân giải động. – Josh

Các vấn đề liên quan