Những câu hỏi hay. Hãy để tôi trình bày lại chúng.
Tại sao lại hợp pháp để ẩn một phương pháp với một phương pháp khác?
Hãy để tôi trả lời câu hỏi đó bằng một ví dụ. Bạn có một giao diện từ CLR v1:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
Siêu. Bây giờ trong CLR v2, bạn có generics và bạn nghĩ "anh bạn, giá như chúng ta có generics trong v1 thì tôi đã làm cho giao diện này trở thành một giao diện chung. Nhưng tôi đã không làm như vậy. Tôi nên tạo một cái gì đó tương thích với nó bây giờ là chung chung để Tôi nhận được những lợi ích của generic mà không mất khả năng tương thích ngược với mã mà IEnumerable mong đợi. "
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh
Bạn định gọi phương thức GetEnumerator là IEnumerable<T>
gì? Hãy nhớ rằng, bạn muốn nó ẩn GetEnumerator trên giao diện cơ sở không chung chung. Bạn không bao giờ muốn thứ đó được gọi trừ khi bạn đang ở trong một tình huống tính toán ngược một cách rõ ràng.
Điều đó một mình biện minh cho phương pháp ẩn. Để biết thêm suy nghĩ về cách biện minh của phương pháp ẩn, hãy xem bài viết của tôi về chủ đề này .
Tại sao ẩn mà không có "mới" gây ra một cảnh báo?
Bởi vì chúng tôi muốn bạn biết rằng bạn đang che giấu điều gì đó và có thể vô tình làm điều đó. Hãy nhớ rằng, bạn có thể vô tình che giấu điều gì đó do việc chỉnh sửa lớp cơ sở do người khác thực hiện, chứ không phải do bạn chỉnh sửa lớp dẫn xuất của mình.
Tại sao ẩn mà không có "mới" là một cảnh báo hơn là một lỗi?
Cùng một lý do. Bạn có thể vô tình che giấu điều gì đó vì bạn vừa chọn một phiên bản mới của lớp cơ sở. Việc này xảy ra mọi lúc. FooCorp tạo ra một lớp cơ sở B. BarCorp tạo một lớp dẫn xuất D với một Thanh phương thức, bởi vì khách hàng của họ thích phương thức đó. FooCorp nhìn thấy điều đó và nói này, đó là một ý tưởng hay, chúng ta có thể đưa chức năng đó vào lớp cơ sở. Họ làm như vậy và gửi một phiên bản mới của Foo.DLL, và khi BarCorp chọn phiên bản mới, sẽ thật tuyệt nếu họ được thông báo rằng phương thức của họ hiện ẩn phương thức lớp cơ sở.
Chúng tôi muốn tình huống đó là một cảnh báo chứ không phải là một lỗi bởi vì biến nó thành một lỗi có nghĩa là đây là một dạng khác của vấn đề lớp cơ sở giòn . C # đã được thiết kế cẩn thận để khi ai đó thực hiện thay đổi đối với lớp cơ sở, các tác động lên mã sử dụng lớp dẫn xuất được giảm thiểu.
Tại sao ẩn và không ghi đè mặc định?
Vì ghi đè ảo rất nguy hiểm . Ghi đè ảo cho phép các lớp dẫn xuất thay đổi hành vi của mã đã được biên dịch để sử dụng các lớp cơ sở. Làm điều gì đó nguy hiểm như ghi đè phải là việc bạn làm một cách có ý thức và có chủ ý , không phải do ngẫu nhiên.