2014-07-22 15 views
13

Tôi đang chuẩn bị cho C# EXAM của mình là gì. Tôi đang bối rối về câu trả lời cho câu hỏi này:Lý do thực hiện IEnumerable và IEnumerator

Một chương trình có thể sử dụng các giao diện IEnumerableIEnumerator làm nào sau đây?

a. Sử dụng MoveNext và Reset để di chuyển qua danh sách các đối tượng.
b. Sử dụng foreach để di chuyển qua danh sách các đối tượng.
c. Di chuyển qua danh sách các đối tượng theo chỉ mục.
d. Sử dụng báo cáo trả về lợi nhuận để tạo danh sách các đối tượng để lặp lại.

Câu trả lời của tôi là b). Nhưng cuốn sách: Bộ công cụ chứng nhận MCSD nói rằng đó là a).

Ai đó có thể cho tôi biết lý do không? Tôi nhận thấy rằng bạn có thể lấy số Enumerator bằng cách sử dụng GetEnumerator() và sau đó gọi các phương thức MoveNextReset để di chuyển qua danh sách (và sử dụng Current để truy cập phần tử hiện tại được tham chiếu bởi trình lặp). Nhưng không triển khai IEnumerableIEnumerator lý do cho một đối tượng được sử dụng trong vòng lặp foreach?

+1

Từ MSDN: 'Đó là một thực hành tốt nhất để thực hiện IEnumerable và IEnumerator trên lớp sưu tập của bạn để cho phép các foreach (For Each trong Visual Basic) cú pháp, tuy nhiên thực hiện IEnumerable không required.' –

+1

Vì vậy, bạn đang nói rằng bởi vì câu hỏi nói cả IEnumerable và IEnUMERATOR, nên là a). Cảm ơn rất nhiều Hank. Bạn đã làm cho ngày của tôi! – user3509153

+6

Tôi ghét những loại câu hỏi này. Họ kiểm tra bạn về khả năng của bạn để giải mã các câu hỏi mơ hồ/không rõ ràng hơn là kiến ​​thức của bạn về chủ đề này. –

Trả lời

4

Câu trả lời đúng là một và điều này là rõ ràng nếu bạn có một cái nhìn tại các định nghĩa của các giao diện:

[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")] 
[ComVisibleAttribute(true)] 
public interface IEnumerable 
{ 
    IEnumerator GetEnumerator(); 
} 

[ComVisibleAttribute(true)] 
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")] 
public interface IEnumerator 
{ 
    Object Current { get; } 
    bool MoveNext(); 
    void Reset(); 
} 

Như bạn thấy ở đây, khi một loại thực hiện giao diện IEnumerable, nó sẽ có một phương thức sẽ trả về một Bộ đếm, một đối tượng thực hiện giao diện IEnumerator.

Sau đó, giao diện được gọi là IEnumerator có một thuộc tính chứa đối tượng hiện tại, khi chúng tôi lặp qua bộ sưu tập và hai phương pháp, MoveNextReset. Dưới mui xe, khi chúng tôi lặp qua bộ sưu tập, phương pháp của Iterator có tên là MoveNext được gọi lúc đầu. Nếu điều này đúng, chúng ta sẽ có được phần tử đầu tiên - đó là đối tượng hiện tại. Sau đó, phương thức được gọi là MoveNext được gọi lại và cho đến khi nó trả về false. Mỗi lần MoveNext được gọi là chúng tôi nhận được một đối tượng từ bộ sưu tập, chúng tôi lặp lại thông qua.

Tại sao chúng tôi có phương thức Reset?

Vì nó được nêu trong MSDN:

Thiết lập các điều tra viên về vị trí ban đầu của nó, đó là trước khi phần tử đầu tiên trong bộ sưu tập.

+0

Nhưng chính xác điều này có lợi cho a) trên b) như thế nào? Tôi đã từng nghĩ rằng 'foreach()' cần những giao diện đó. Nó cần chính xác chức năng của họ. –

+0

@ HenkHolterman Tôi nghĩ rằng nên được ưu tiên hơn b, bởi vì foreach sử dụng các phương pháp này để thực hiện phép lặp mà foreach thực hiện. Nó đề cập đến các bên trong. Ngay cả khi chúng tôi không có tuyên bố 'foreach() ', chúng tôi đã có thể bắt chước nó bằng cách sử dụng những phương pháp này. Tôi đồng ý 100% với bạn nói rằng 'foreach()' yêu cầu từ bộ sưu tập để thực hiện các giao diện này. – Christos

1

Khi bạn triển khai giao diện, bạn đồng ý với hợp đồng: MoveNext và Đặt lại. Các tùy chọn khác cho câu hỏi đề cập đến các lớp cụ thể thực hiện giao diện.

0

Nếu MoveNext vượt qua cuối bộ sưu tập, điều tra viên được định vị sau phần tử cuối cùng trong bộ sưu tập và MoveNext trả về false. Khi điều tra viên ở vị trí này, các cuộc gọi tiếp theo tới MoveNext cũng trả về false. Nếu cuộc gọi cuối cùng để MoveNext trả về false, Current is undefined. Để đặt Hiện tại thành phần tử đầu tiên của bộ sưu tập một lần nữa, bạn có thể gọi Đặt lại theo sau bởi MoveNext.

click here for detailed explanation

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