2009-08-13 30 views
7

Với Java Iterator s, tôi đã sử dụng phương pháp hasNext để xác định xem một phép lặp có nhiều phần tử hơn (không tiêu thụ một phần tử) hay không - do đó, hasNext giống như phương thức "Peek".Có phương pháp "HasNext" cho IEnumerator không?

Câu hỏi của tôi: có bất kỳ điều gì giống như phương thức "hasNext" hoặc "Peek" với C# 'chung chung IEnumerator s không?

+5

Làm sao bạn có thể không biết? Có thể bạn chưa từng thấy http://msdn.microsoft.com/en-us/library/78dfe2yb.aspx? –

+0

Cảm ơn bạn rất nhiều vì đã chỉ ra điều này, ông Saunders. – JaysonFix

Trả lời

15

Không, rất tiếc là không có.

Giao diện IEnumerator<T> chỉ cho thấy các thành viên sau:

Phương pháp:

Dispose
MoveNext
Reset

Prope rties:

Current

+1

Cảm ơn bạn, Andrew. – JaysonFix

+1

Chúng tôi đang dùng về IEnumerator, thay vì IEnumerable ở đây, phải không? Và * nên được vứt bỏ, thay vì MoveNext. –

+0

@Even - Yikes, bài đăng đó có nhiều lỗi! Cảm ơn bạn đã chỉ cho họ. –

2

Nope, chỉ MoveNext, ResetCurrent.

33

Không, nhưng trong C# bạn có thể liên tục yêu cầu phần tử hiện tại mà không cần chuyển sang phần tử tiếp theo. Nó chỉ là một cách nhìn khác.

Nó sẽ không được quá khó để viết lớp C# để có kiểu .NET IEnumerator và trả về kiểu Java Iterator. Cá nhân tôi thấy phong cách .NET dễ sử dụng hơn trong hầu hết các trường hợp, nhưng chúng tôi đi :)

CHỈNH SỬA: Được rồi, điều này hoàn toàn chưa được kiểm tra, nhưng tôi nghĩ rằng nó sẽ hoạt động. Nó ít nhất biên dịch :)

using System; 
using System.Collections; 
using System.Collections.Generic; 

// // Mimics Java's Iterable<T> interface 
public interface IIterable<T> 
{ 
    IIterator<T> Iterator(); 
} 

// Mimics Java's Iterator interface - but 
// implements IDisposable for the sake of 
// parity with IEnumerator. 
public interface IIterator<T> : IDisposable 
{ 
    bool HasNext { get; } 
    T Next(); 
    void Remove(); 
} 

public sealed class EnumerableAdapter<T> : IIterable<T> 
{ 
    private readonly IEnumerable<T> enumerable; 

    public EnumerableAdapter(IEnumerable<T> enumerable) 
    { 
     this.enumerable = enumerable; 
    } 

    public IIterator<T> Iterator() 
    { 
     return new EnumeratorAdapter<T>(enumerable.GetEnumerator()); 
    } 
} 

public sealed class EnumeratorAdapter<T> : IIterator<T> 
{ 
    private readonly IEnumerator<T> enumerator; 

    private bool fetchedNext = false; 
    private bool nextAvailable = false; 
    private T next; 

    public EnumeratorAdapter(IEnumerator<T> enumerator) 
    { 
     this.enumerator = enumerator; 
    } 

    public bool HasNext 
    { 
     get 
     { 
      CheckNext(); 
      return nextAvailable; 
     } 
    } 

    public T Next() 
    { 
     CheckNext(); 
     if (!nextAvailable) 
     { 
      throw new InvalidOperationException(); 
     } 
     fetchedNext = false; // We've consumed this now 
     return next; 
    } 

    void CheckNext() 
    { 
     if (!fetchedNext) 
     { 
      nextAvailable = enumerator.MoveNext(); 
      if (nextAvailable) 
      { 
       next = enumerator.Current; 
      } 
      fetchedNext = true;    
     } 
    } 

    public void Remove() 
    { 
     throw new NotSupportedException(); 
    } 

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

public sealed class IterableAdapter<T> : IEnumerable<T> 
{ 
    private readonly IIterable<T> iterable; 

    public IterableAdapter(IIterable<T> iterable) 
    { 
     this.iterable = iterable; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return new IteratorAdapter<T>(iterable.Iterator()); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public sealed class IteratorAdapter<T> : IEnumerator<T> 
{ 
    private readonly IIterator<T> iterator; 

    private bool gotCurrent = false; 
    private T current; 

    public IteratorAdapter(IIterator<T> iterator) 
    { 
     this.iterator = iterator; 
    } 

    public T Current 
    { 
     get 
     { 
      if (!gotCurrent) 
      { 
       throw new InvalidOperationException(); 
      } 
      return current; 
     } 
    } 

    object IEnumerator.Current 
    { 
     get { return Current; } 
    } 

    public bool MoveNext() 
    { 
     gotCurrent = iterator.HasNext; 
     if (gotCurrent) 
     { 
      current = iterator.Next(); 
     } 
     return gotCurrent; 
    } 

    public void Reset() 
    { 
     throw new NotSupportedException(); 
    } 

    public void Dispose() 
    { 
     iterator.Dispose(); 
    } 
} 
+0

+1 Nó thực sự chỉ là một sự khác biệt trên cùng một mẫu. –

+0

(Tôi rất vui khi mã hóa bộ điều hợp nếu có ai quan tâm, nhưng tôi sẽ không làm điều đó nếu không ...) –

+3

Tôi muốn được nhìn thấy nó, Jon. – JaysonFix

3

ĐTV thường được đánh giá rất lười để HasNext có ý nghĩa rất ít.

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