2010-09-02 29 views
6

Hãy nói rằng tôi có một lớp (ClassA) chứa một phương pháp trong đó kêu gọi các nhà xây dựng của lớp khác, như thế này:Tại sao tôi buộc phải tham khảo các loại trong các nhà thầu chưa sử dụng?

public class ClassA 
{ 
    public void CallClassBConstructor() 
    { 
     using(ClassB myB = new ClassB()) {...} 
    } 
} 

Lớp ClassB trông như thế này:

public class ClassB : IDisposable 
{ 
    public ClassB(){} 
    public ClassB(string myString){} 
    public ClassB(ClassC myC){} 
    public void Dispose() {...} 
} 

... và ClassC thậm chí còn đơn giản hơn:

public class ClassC{} 

Nếu tôi đặt các lớp này vào ass của chính chúng embly và biên dịch toàn bộ giải pháp Tôi không nhận được bất kỳ lỗi nào. Nhưng nếu tôi thay thế báo cáo kết quả sử dụng với điều này:

using(ClassB myB = new ClassB("mystring")){...} 

tôi nhận được một lỗi biên dịch yêu cầu tôi thêm một tham chiếu đến [mynamespace].ClassC trong ClassA. Vì tôi không gọi ClassB(ClassC myC) ở tất cả điều này không có ý nghĩa với tôi - tại sao tôi phải bao gồm các loại nhà xây dựng khác bất kể tôi có sử dụng chúng hay không? Điều gì xảy ra nếu ClassC được bao gồm trong một hội đồng được cấp phép hoặc khó khăn? Đây có phải là một ví dụ về thiết kế xấu mà các nhà phát triển nên tránh hoặc tôi thiếu một cái gì đó ở đây?

+3

Điều này không thể biên dịch ngay từ đầu, ClassB không thực hiện IDisposable. Sau đó, nó không thể được sử dụng trong một mệnh đề sử dụng. –

+0

Đây không phải là C/C++ khi mã không sử dụng không hợp lệ sẽ bị bỏ qua nếu các phần được gc'd bởi trình liên kết. – leppie

+0

Tôi đã chỉnh sửa mã để biên dịch ngay bây giờ –

Trả lời

9

Nó phải làm với độ phân giải quá tải phương thức khi gọi hàm tạo ClassB.

Khi bạn gọi hàm tạo không có tham số, không có tranh chấp. Chỉ có một ứng cử viên, vì vậy nó được chọn. Không cần thiết cho ClassA để tham chiếu ClassC trong trường hợp này.

Tuy nhiên, khi bạn gọi hàm tạo với một tham số, thì lúc đầu cả hai hàm tạo tham số đơn là các ứng cử viên. Để giải quyết cuộc gọi này, trình biên dịch cần biết về ClassC. Đối với tất cả những gì bạn biết, ví dụ: ClassC có thể chứa một toán tử chuyển đổi tiềm ẩn. Tất nhiên chúng ta biết rằng trong ví dụ cụ thể này, một toán tử chuyển đổi tiềm ẩn sẽ không cháy vì có một kết hợp hoàn hảo cần một chuỗi - nhưng quy tắc phân giải quá tải phương thức được xác định theo cách này để làm cho chúng rất tốt Hãy tưởng tượng nó được thiết kế theo cách bổ sung một tham chiếu có thể làm cho mã của bạn đột nhiên gọi quá tải khác nhau.)

+0

Cảm ơn Timwi, tôi nghĩ rằng tất cả các câu trả lời đã làm cho nó khá rõ ràng với tôi :-) –

+0

một câu lệnh 'using' bị thiếu là không đủ để trình biên dịch biết được quá tải nào cần sử dụng? Tôi nhầm lẫn rằng chỉ cần thêm tham chiếu làm cho trình biên dịch trở nên hạnh phúc. – Stijn

+0

@Stijn: Bạn có thể có nghĩa là ['using' directive] (http://msdn.microsoft.com/en-us/library/sf0df423.aspx), * not * the [' using' statement] (http://msdn.microsoft.com/en-us/library/yh598w02.aspx). Nhưng ngay cả như vậy, cả câu hỏi lẫn câu trả lời của tôi đều không liên quan gì đến câu lệnh 'using' statements * hay *' using'. Họ là về [tham chiếu đến các hội đồng khác] (http://msdn.microsoft.com/en-us/library/wkze6zky%28v=vs.80%29.aspx). Khai báo 'using' không thêm tham chiếu như vậy. – Timwi

1

Để giải quyết quá tải hàm dựng, trình biên dịch cần biết các loại có liên quan. I E. nó cần phải biết ClassC để chọn đúng quá tải hàm xây dựng cho ClassB.

+0

Cảm ơn câu trả lời của bạn Brian - nó phù hợp độc đáo với các câu trả lời khác –

1

Đó là vì ClassC, mà bạn đã đặt trong một hội đồng riêng biệt, là một phần của giao diện công khai của ClassB vì nó là một tham số của một trong các hàm tạo. Bạn phải tham chiếu đến assembly chứa kiểu này nếu không trình biên dịch không biết cách giải quyết thông tin kiểu. Trong trường hợp cụ thể này, trình biên dịch phải giải quyết tất cả các kiểu tham số từ tất cả các quá tải của hàm dựng để nó có thể chọn đúng, nhưng đây không phải là vấn đề quá tải thành viên cho mỗi se. Điều này xảy ra bất cứ lúc nào trình biên dịch phải giải quyết thông tin kiểu. Nó cũng có thể xảy ra với kiểu trả về.

+0

Tại sao lưu ý lại? Ngay cả trước khi tôi chỉnh sửa câu trả lời này là không sai. –

+0

Tôi xin lỗi tôi mới trên stackoverflow nhưng tôi đã không nhấp vào bất cứ điều gì, chỉ cần tải lại trang. Có lẽ đó là lý do tại sao nó đã được downvoted? –

+0

@boomshanka: Không, bạn không làm gì cả. Có người nghĩ rằng câu trả lời này là sai hoặc có hại hơn là hữu ích. Tôi đứng sau câu trả lời của tôi. –

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