2010-04-26 27 views
5

Tôi đang chuyển một thư viện từ C++ sang C#. Thư viện cũ sử dụng vectơ từ C++ và trong C# Tôi đang sử dụng từ điển chung vì chúng thực sự là cấu trúc dữ liệu tốt cho những gì tôi đang làm (mỗi phần tử có ID, sau đó tôi chỉ sử dụng TypeDictionary = Dictionary<String, Type>;). Bây giờ, trong mã C# tôi sử dụng một vòng lặp như thế nàyLàm thế nào để biết liệu một điều tra viên đã đến cuối bộ sưu tập trong C# chưa?

TypeDictionary.Enumerator tdEnum = MyTypeDictionary.GetEnumerator(); 

while(tdEnum.MoveNext()) 
{ 
    Type element = typeElement.Current.Value; 

    // More code here 
} 

để lặp qua các phần tử của bộ sưu tập. Vấn đề là trong những trường hợp đặc biệt tôi cần phải kiểm tra xem một Enumerator nhất định đã đạt đến kết thúc của bộ sưu tập, trong C++ Tôi đã có thể làm một kiểm tra như thế này:

if (tdEnum == MyTypeDictionary.end()) // More code here 

Nhưng tôi chỉ không biết làm thế nào để xử lý tình huống này trong C#, bất kỳ ý tưởng nào?

Cảm ơn bạn
Tommaso

Trả lời

3

Bạn biết rằng bạn đang ở phần cuối của một iterator khi MoveNext() lợi nhuận false. Nếu không, bạn cần nâng cấp lên cấu trúc dữ liệu mô tả hơn như IList<T>.

4

Tôi có lớp "trình lặp thông minh" trong MiscUtil mà bạn có thể thấy hữu ích. Nó cho phép bạn kiểm tra xem bạn hiện đang nhìn vào đầu hoặc cuối chuỗi và chỉ mục trong chuỗi. Xem usage page để biết thêm thông tin.

Tất nhiên trong hầu hết các trường hợp, bạn chỉ có thể lấy đi bằng cách thực hiện việc này theo cách thủ công bằng kết quả của MoveNext(), nhưng đôi khi việc đóng gói bổ sung có ích. Lưu ý rằng bởi sự cần thiết, trình lặp này sẽ luôn luôn thực sự tiêu thụ một giá trị nhiều hơn nó mang lại, để biết có hay không nó đã đạt đến kết thúc. Trong hầu hết các trường hợp không phải là một vấn đề, nhưng đôi khi nó có thể mang lại một số trải nghiệm kỳ lạ khi gỡ lỗi.

+0

Cảm ơn bạn cho thư viện của bạn, tôi đã đánh dấu nó, nhưng đối với lần này tôi sẽ chỉ đi với các giải pháp nhanh chóng. :) – tunnuz

1

Đến từ C++, bạn có thể không cập nhật cú pháp C#. Có lẽ bạn chỉ đơn giản là có thể sử dụng cấu trúc foreach để tránh kiểm tra tất cả cùng nhau. Mã sau sẽ được thực hiện một lần cho mỗi phần tử trong từ điển của bạn:

foreach (var element in MyTypeDictionary) 
{ 
    // More code here 
} 
2

Sử dụng mẫu trang trí để giữ giá trị nếu điều tra đã kết thúc là một phương pháp hợp lệ. Vì nó thực hiện IEnumerator, bạn sẽ không tìm thấy khó khăn để thay thế nó trong mã của bạn.

Dưới đây là một lớp học thử nghiệm:

using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using MyDictionary = System.Collections.Generic.Dictionary<int, string>; 
using MyKeyValue = System.Collections.Generic.KeyValuePair<int, string>; 

namespace TestEnumerator 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestingMyEnumeradorPlus() 
     { 
      var itens = new MyDictionary() 
      { 
       { 1, "aaa" }, 
       { 2, "bbb" } 
      }; 
      var enumerator = new EnumeradorPlus<MyKeyValue>(itens.GetEnumerator()); 
      enumerator.MoveNext(); 
      Assert.IsFalse(enumerator.Ended); 
      enumerator.MoveNext(); 
      Assert.IsFalse(enumerator.Ended); 
      enumerator.MoveNext(); 
      Assert.IsTrue(enumerator.Ended); 
     } 
    } 

    public class EnumeradorPlus<T> : IEnumerator<T> 
    { 
     private IEnumerator<T> _internal; 
     private bool _hasEnded = false; 

     public EnumeradorPlus(IEnumerator<T> enumerator) 
     { 
      _internal = enumerator; 
     } 

     public T Current 
     { 
      get { return _internal.Current; } 
     } 

     public void Dispose() 
     { 
      _internal.Dispose(); 
     } 

     object System.Collections.IEnumerator.Current 
     { 
      get { return _internal.Current; } 
     } 

     public bool MoveNext() 
     { 
      bool moved = _internal.MoveNext(); 
      if (!moved) 
       _hasEnded = true; 
      return moved; 
     } 

     public void Reset() 
     { 
      _internal.Reset(); 
      _hasEnded = false; 
     } 

     public bool Ended 
     { 
      get { return _hasEnded; } 
     } 
    } 
} 
+0

Enumera ** d ** hoặc? typo? Nên là Enumera ** t ** hoặc – IlPADlI

+1

Có, xem xét ví dụ đã được viết bằng tiếng Anh, đó là một lỗi đánh máy (mặc dù trong ngôn ngữ mẹ đẻ của tôi đó là từ "điều tra viên"). Tuy nhiên, đó là tên lớp, vì vậy nó không ảnh hưởng đến kết quả. – Fabio

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