Tôi đã suy nghĩ về phương pháp IEnumerator.Reset()
. Tôi đọc trong tài liệu MSDN rằng nó chỉ có cho COM interop. Là một lập trình viên C++, nó trông giống như một IEnumerator
hỗ trợ Reset
là những gì tôi gọi là forward iterator, trong khi IEnumerator
không hỗ trợ Reset
thực sự là một input iterator.Liệu C# có được hưởng lợi từ sự phân biệt giữa các loại điều tra viên, như trình lặp C++ không?
Vì vậy, một phần của câu hỏi của tôi là, sự hiểu biết này có chính xác không?
Phần thứ hai của câu hỏi của tôi là, nó sẽ có lợi ích nào trong C# nếu có sự phân biệt giữa các trình vòng lặp đầu vào và vòng lặp chuyển tiếp (hoặc "điều tra viên" nếu bạn thích)? Nó sẽ không giúp loại bỏ một số nhầm lẫn giữa các lập trình viên, giống như một trong số này được tìm thấy trong số SO question about cloning iterators này?
CHỈNH SỬA: Làm rõ trên các trình vòng lặp chuyển tiếp và đầu vào. Trình lặp đầu vào chỉ đảm bảo rằng bạn có thể liệt kê các thành viên của một bộ sưu tập (hoặc từ một hàm máy phát hoặc một luồng đầu vào) chỉ một lần. Đây chính là cách IEnumerator hoạt động trong C#. Cho dù bạn có thể liệt kê lần thứ hai hay không, được xác định là có hay không Reset
được hỗ trợ. Trình vòng lặp chuyển tiếp, không có hạn chế này. Bạn có thể liệt kê các thành viên thường xuyên như bạn muốn.
Một số lập trình viên C# không hiểu tại sao một số IEnumerator
không thể được sử dụng một cách đáng tin cậy trong thuật toán đa. Hãy xem xét các trường hợp sau đây:
void PrintContents(IEnumerator<int> xs)
{
while (iter.MoveNext())
Console.WriteLine(iter.Current);
iter.Reset();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
}
Nếu chúng ta gọi là PrintContents
trong bối cảnh này, không có vấn đề:
List<int> ys = new List<int>() { 1, 2, 3 }
PrintContents(ys.GetEnumerator());
Tuy nhiên nhìn vào những điều sau đây:
IEnumerable<int> GenerateInts() {
System.Random rnd = new System.Random();
for (int i=0; i < 10; ++i)
yield return Rnd.Next();
}
PrintContents(GenerateInts());
Nếu IEnumerator
hỗ trợ Reset
, trong các từ khác hỗ trợ các thuật toán đa truyền, sau đó mỗi lần bạn lặp lại bộ sưu tập thì nó sẽ khác nhau. Điều này sẽ là không mong muốn, bởi vì nó sẽ là hành vi đáng ngạc nhiên. Ví dụ này hơi giả, nhưng nó xảy ra trong thế giới thực (ví dụ: đọc từ luồng tệp).
Tôi nghĩ bạn có nghĩa là 'IEnumerator.Reset', không phải là 'IEnumerable .Reset', phải không? –
Vâng, cảm ơn bạn! Xin lỗi vì điều đó. – cdiggins
Câu hỏi thú vị. Nhưng có lẽ bạn nên giải thích C++ - nói một chút, vì rất nhiều lập trình viên C# sẽ thấy điều này. Nó có thể không được rõ ràng những gì một iterator đầu vào và chuyển tiếp về phía trước là, chính xác (đặc biệt, khả năng đơn/multipass của họ, đó là những gì thực sự có liên quan đến câu hỏi này) – jalf