CẬP NHẬT: Câu hỏi này là cơ sở của my blog entry for Monday April 4th 2011. Cảm ơn vì câu hỏi tuyệt vời của bạn.
Hãy để tôi chia nhỏ thành nhiều câu hỏi nhỏ hơn.
Có List<T>
thực sự triển khai tất cả các giao diện đó không?
Có.
Tại sao?
Bởi vì khi một giao diện (nói, IList<T>
) được thừa hưởng từ một giao diện (nói IEnumerable<T>
) sau đó người thực hiện của giao diện có nguồn gốc hơn được yêu cầu cũng để thực hiện các giao diện ít có nguồn gốc. Đó là ý nghĩa của giao diện; nếu bạn thực hiện hợp đồng của loại có nguồn gốc nhiều hơn thì bạn cũng phải thực hiện hợp đồng của loại có nguồn gốc ít hơn.
Vì vậy, một lớp học được yêu cầu triển khai tất cả các phương pháp của tất cả các giao diện trong giao diện cơ bản của giao diện cơ sở?
Chính xác.
Một lớp thực hiện giao diện có nguồn gốc nhiều hơn cũng cần phải nêu trong danh sách kiểu cơ sở của nó là nó đang triển khai tất cả các giao diện ít xuất phát đó?
số
là lớp cần thiết để không nêu nó?
số
Vì vậy, nó tùy chọn liệu các giao diện thực hiện ít có nguồn gốc từ được nêu trong danh sách loại hình cơ bản?
Có.
Luôn luôn?
Hầu như luôn luôn:
interface I1 {}
interface I2 : I1 {}
interface I3 : I2 {}
Nó là tùy chọn cho dù I3 nói rằng nó được thừa hưởng từ I1.
class B : I3 {}
Người triển khai I3 được yêu cầu triển khai I2 và I1, nhưng không bắt buộc phải nêu rõ là họ đang làm như vậy. Nó là tùy chọn.
class D : B {}
Các lớp bắt buộc không bắt buộc phải nói lại rằng chúng triển khai giao diện từ lớp cơ sở của chúng, nhưng được phép làm như vậy. (Trường hợp này là đặc biệt; xem bên dưới để biết thêm chi tiết.)
class C<T> where T : I3
{
public virtual void M<U>() where U : I3 {}
}
Đối số kiểu tương ứng với T và U được yêu cầu triển khai I2 và I1, nhưng không bắt buộc đối với các ràng buộc trên T hoặc U.
Nó luôn luôn là không bắt buộc phải tái trạng thái bất kỳ giao diện cơ sở trong một lớp học phần:
partial class E : I3 {}
partial class E {}
Phần thứ hai của E được phép nói rằng nó thực hiện I3 hoặc I2 hoặc I1, nhưng không bắt buộc phải làm vì thế.
OK, tôi hiểu; nó là tùy chọn. Tại sao bất cứ ai không cần thiết phải nêu một giao diện cơ bản?
Có lẽ vì họ tin rằng làm như vậy giúp mã dễ hiểu hơn và tự tài liệu hơn.
Hoặc, có lẽ các nhà phát triển viết mã như
interface I1 {}
interface I2 {}
interface I3 : I1, I2 {}
và nhận ra, oh, chờ một phút, I2 nên kế thừa từ I1.Tại sao nên thực hiện chỉnh sửa đó sau đó yêu cầu nhà phát triển quay trở lại và thay đổi tuyên bố của I3 thành không phải có đề cập rõ ràng về I1? Tôi thấy không có lý do để buộc các nhà phát triển để loại bỏ thông tin dư thừa.
Bên cạnh là dễ dàng hơn để đọc và hiểu, là có bất kỳ kỹ thuật chênh lệch giữa nêu một giao diện một cách rõ ràng trong danh sách loại cơ sở và để lại nó unstated nhưng ngụ ý?
Thường thì không, nhưng có thể có sự khác biệt tinh tế trong một trường hợp. Giả sử bạn có một lớp dẫn xuất D có lớp cơ sở B đã triển khai một số giao diện. D tự động thực hiện các giao diện đó thông qua B. Nếu bạn tái xác nhận các giao diện trong danh sách lớp cơ sở của D thì trình biên dịch C# sẽ thực hiện một giao diện tái triển khai. Các chi tiết có một chút tinh tế; nếu bạn quan tâm đến cách làm việc này thì tôi khuyên bạn nên đọc kỹ phần 13.4.6 của đặc tả C# 4.
Mã nguồn List<T>
có thực sự nêu tất cả các giao diện đó không?
số Mã nguồn thực tế nói
public class List<T> : IList<T>, System.Collections.IList
Tại sao MSDN có danh sách giao diện đầy đủ nhưng mã nguồn thực không?
Vì MSDN là tài liệu; nó phải cung cấp cho bạn nhiều thông tin như bạn muốn. Nó là rõ ràng hơn cho các tài liệu được hoàn thành tất cả ở một nơi hơn để làm cho bạn tìm kiếm thông qua mười trang khác nhau để tìm ra những gì giao diện đầy đủ thiết lập được.
Tại sao trình phản chiếu hiển thị toàn bộ danh sách?
Trình phản xạ chỉ có siêu dữ liệu để hoạt động. Kể từ khi đưa vào danh sách đầy đủ là tùy chọn, Reflector không có ý tưởng cho dù mã nguồn ban đầu có chứa danh sách đầy đủ hay không. Nó là tốt hơn để err ở phía bên của thông tin nhiều hơn nữa. Một lần nữa, Reflector đang cố gắng giúp bạn bằng cách hiển thị cho bạn nhiều thông tin hơn là ẩn thông tin bạn có thể cần.
THƯỞNG HỎI: Tại sao IEnumerable<T>
kế thừa từ IEnumerable
nhưng IList<T>
không kế thừa từ IList
?
Một chuỗi các số nguyên có thể được coi là một chuỗi các đối tượng, bằng cách giải nén mọi số nguyên khi nó xuất hiện trong chuỗi. Nhưng một danh sách đọc-viết của các số nguyên không thể được coi là một danh sách đọc-ghi các đối tượng, bởi vì bạn có thể đặt một chuỗi vào một danh sách đọc-ghi các đối tượng. An IList<T>
không bắt buộc phải hoàn thành toàn bộ hợp đồng IList
, vì vậy nó không được thừa hưởng từ nó.
Có danh sách thực hiện tất cả các giao diện đó, tại sao - bởi vì tất cả chúng đều có liên quan đến bộ sưu tập danh sách. Mã của bạn là gì? Đó có phải là một câu hỏi khác không? –
mẫu mã của bạn không có gì để làm với các Danh sách lớp '' ... –
BoltClock
Tôi nghĩ anh ta hỏi tại sao 'công cộng Danh sách lớp: IList , ICollection , IEnumerable , etc.' thay vì chỉ' Danh sách public class : IList '. Lưu ý rằng 'ICollection' và' IList' (những cái không chung) không được thừa kế từ 'IList '. –
Rup