2010-12-10 22 views
6

Khi triển khai IList<T>, tôi thấy rằng tôi được yêu cầu xác định hai phương thứcGetEnumerator. Một trả về một giá trị thuộc loại IEnumerator, trong khi giá trị kia trả về IEnumerator<T>.Tại sao việc triển khai 'IList <T>' yêu cầu xác định hai phương thức 'GetEnumerator'?

Tôi hơi bối rối về sự khác biệt giữa hai phương thức GetEnumerator này. Trong khi các kiểu trả về rõ ràng là khác nhau, về cơ bản chúng không giữ cùng một dữ liệu?

Ngoài ra, tại sao cả hai phiên bản GetEnumerator đều có thể tồn tại dưới dạng phương thức khi chúng chỉ khác nhau theo loại trả về? Điều này có vẻ vi phạm quy tắc trong C# chỉ định rằng các phương thức quá tải không thể chỉ khác nhau theo loại trả về.

Trả lời

8

Cả hai đều phải trả lại cùng một dữ liệu, vâng.

IEnumerator là từ .Net v1.1, trước khi nhập chung được đưa vào. IEnumerator<T> là phiên bản được nhập chung được thêm vào .Net v2.

Phiên bản "cũ", IEnumerator, đã được giữ để tương thích, vì vậy, bây giờ IList<T> thực hiện cả hai.

Sự khác biệt giữa hai là không chung chung IEnumerator trả về đối tượng trong khi chung IEnumerator<T> trả về T's. Mặc dù, trình biên dịch C# sẽ chèn một dàn diễn viên cho bạn để làm cho không chung chung IEnumeratordường như được đánh máy mạnh khi được sử dụng trong foreach.

Sự hiện diện của đối số kiểu chung là đủ để trình biên dịch phân biệt giữa hai giao diện, nhưng đối với một lớp để triển khai cả hai giao diện phải được triển khai một cách rõ ràng.

+1

Không hoàn toàn đúng, đối số chung là không đủ - một được thực hiện một cách rõ ràng, cái kia thì không. –

+1

Tôi hầu như không gọi việc sử dụng không phổ biến của IEnumerator trong một phép thuật vòng lặp foreach. Nó chỉ đơn giản là cố gắng một diễn viên từ đối tượng đến loại bạn chỉ định. Nếu không thành công, bạn sẽ nhận được Ngoại lệ. –

+0

Được chấp nhận để giải thích vấn đề tương thích ngược. Cảm ơn. – MyNameIsJob

7

Hai đến từ giao diện riêng biệt mà IList bản thân thực hiện, đó là lý do tại sao bạn cần phải thực hiện cả hai:

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable 

Và chúng đều có khả năng tồn tại vì Explicit Interface Implementation.

+0

Cám ơn liên kết đó. Điều đó giúp ích nhiều hơn bất cứ điều gì. – MyNameIsJob

3

Có, cả hai phương pháp đều phải trả về cùng một dữ liệu.

Chúng có thể cùng tồn tại vì chúng là một phần của hai giao diện khác nhau, IEnumerableIEnumerable<T>.

0

IList<T> Thực hiện cả hai IEnumerable<T>IEnumerable. Việc triển khai khác nhau của GetEnumerator đến từ mỗi giao diện này. Cả hai sẽ trả về cùng một dữ liệu.

1

Cả hai đều có thể tồn tại bởi vì một trong số họ sẽ được thực hiện explicitly:

IEnumerator IEnumerable.GetEnumerator() 
{ 

} 

Nếu bạn cố gắng làm cho họ cả ngầm xác định, bạn sẽ nhận được biên dịch lỗi.

Có, cả hai đều nên trả về cùng một dữ liệu.

Bạn được yêu cầu xác định hai phiên bản GetEnumerator để đáp ứng cả hai giao diện (IEnumerableIEnumerable<T>) từ đó bắt nguồn từ IList<T>. Tuy nhiên, trong thực tế, bạn có xu hướng tìm phiên bản không chung chung của GetEnumerator chỉ cần gọi một phiên bản chung trong hầu hết các triển khai.

0

IEnumerator liệt kê các đối tượng, trong khi IEnumerator liệt kê T. Đối với câu hỏi thứ hai của bạn, chức năng thứ hai là đầy đủ:

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 

    } 

vs

public IEnumerator<T> GetEnumerator() 
    { 

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