2011-09-13 48 views
9

thể trùng lặp:
How does the method overload resolution system decide which method to call when a null value is passed?Null đen loại thông số độ phân giải quá tải

Đây là một câu hỏi về việc tại sao các biên dịch sẽ chọn một tình trạng quá tải nhất định khi thông qua một null đen như một tham số, chứng minh bởi string.Format overloads.

string.Format ném một số ArgumentNullException khi sử dụng null cho tham số arg.

string.Format("foo {0}", null); 

Phương thức định dạng có một số tình trạng quá tải.

string.Format(string, object); 
string.Format(string, object[]); 
string.Format(IFormatProvider, string, object[]); 

Chạy qua mã bị biên dịch, ngoại lệ đối với các tham số rỗng bằng chữ được ném từ phương pháp thứ hai. Tuy nhiên, các ví dụ sau đây gọi phương thức đầu tiên ở trên (như mong đợi) và sau đó gọi phương thức thứ hai gọi là thứ ba cuối cùng chỉ trả về "foo".

string x = null; 
string.Format("foo {0}", x); 

string y; 
string.Format("foo {0}", y = null); 

Nhưng string.Format("foo {0}", null) gọi phương thức thứ hai ở trên và dẫn đến ngoại lệ không. Tại sao trình biên dịch quyết định rằng chữ cái trống khớp với chữ ký phương thức thứ hai thay vì chữ ký đầu tiên trong trường hợp này?

+3

Có lẽ mở rộng tiêu đề/phạm vi nếu điều này bao gồm vararg theo nghĩa chung hơn (nếu nó không phải là chuỗi.Định dạng cụ thể) ... –

+0

Pete, bạn có thể biết điều này (và nó không phải là câu trả lời cho bạn) nhưng mặc dù tôi sẽ đề cập đến nó; để tránh ngoại lệ này, bạn có thể sử dụng 'Chuỗi.Định dạng ("Kiểm tra {0}", String.Empty); '. Tất cả là tốt nhất. – MoonKnight

+2

Câu hỏi trùng lặp: http://stackoverflow.com/q/5173339/25727. Tóm lại: Độ phân giải quá tải thích các loại cụ thể hơn. Vì vậy, nó chọn mảng vì 'đối tượng' là loại không xác định nhất trong .NET. – Jan

Trả lời

3

Tôi chỉ đơn giản là đoán rằng object[] cụ thể hơn object và được null được gán cho object[] trước đây được chọn. (7.5.3.2 Thành viên chức năng tốt hơn trong thông số C#).

Cùng xảy ra nếu bạn thử:

void Foo(object o) {} 
void Foo(object[] arr) {} 

Foo(null); //Foo(object[]) gets called. 
0

Không thể cung cấp cho bạn 100% sự chắc chắn nhưng tôi đoán tốt nhất sẽ như sau ...

Nếu tôi đã đích thân viết một trình biên dịch và tôi đã phải đối phó với việc chọn chức năng quá tải nào để sử dụng dựa trên các tham số được truyền, tôi sẽ tự động lặp lại danh sách và tìm ra kết quả phù hợp nhất. Tôi tưởng tượng có một cái gì đó dọc theo những dòng thực hiện trong trình biên dịch C#. Vì vậy, điều này sẽ gợi ý với tôi rằng "quá tải 2" (trong ví dụ của bạn) sớm hơn trong danh sách hơn "quá tải 1" và do đó một kết hợp được tìm thấy và lặp lại bị hỏng, HOẶC trình biên dịch được thiết lập để sử dụng sự quá tải phù hợp sau này.

Tất nhiên, trong 2 ví dụ của bạn, hãy chuyển x và y. Thật dễ dàng để khớp với "overload 1" khi bạn đang đối sánh một chuỗi với đối tượng, trong khi chuỗi không thể khớp với đối tượng [] và do đó "overload 2" không phải là một kết hợp hợp lệ.

Khi bạn trực tiếp vượt qua null thì điều này khớp với cả "quá tải 1" và "quá tải 2" để trở lại điểm được tìm thấy đầu tiên trong danh sách hoặc tìm thấy lần cuối.

EDIT: Vì vậy, nó chỉ ra rằng trình biên dịch cần thiết quyết định dựa trên các thông số cụ thể hơn. Và đối tượng [] nếu cụ thể hơn đối tượng đó.

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