From 8bd79dd5eadf74846bed0633e3e0942da6203252 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 22 Oct 2019 08:26:16 -0600 Subject: [PATCH] Added a generic IEnumerator implementation --- PInvoke/Shared/Collections/IEnumGenerics.cs | 91 ++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 9 deletions(-) diff --git a/PInvoke/Shared/Collections/IEnumGenerics.cs b/PInvoke/Shared/Collections/IEnumGenerics.cs index c36ee260..7957198c 100644 --- a/PInvoke/Shared/Collections/IEnumGenerics.cs +++ b/PInvoke/Shared/Collections/IEnumGenerics.cs @@ -6,6 +6,86 @@ using Vanara.PInvoke; namespace Vanara.Collections { + /// + /// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration. + /// + /// The type of the item. + /// The value, on success, of the next item. + /// true if an item is returned, otherwise false. + public delegate bool TryGetNext(out TItem value); + + /// + /// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration. + /// + /// The type of the enumerator object. + /// The type of the item. + /// The enumerator object. + /// The value, on success, of the next item. + /// true if an item is returned, otherwise false. + public delegate bool TryGetNext(TIEnum enumObj, out TItem value); + + /// An implementation the interface that can iterate through next and reset methods. + public class IEnumeratorFromNext : IEnumerator where TIEnum : class + { + /// The current item being iterated. + protected TItem current; + + /// The object that is enumerated. + protected TIEnum ienum; + + /// The next function delegate. + protected TryGetNext next; + + /// The reset function delegate. + protected Action reset; + + /// Initializes a new instance of the class. + /// The object to be enumerated. + /// The method used to get the next value. + /// The method used to reset the enumeration. + /// Thrown if any parameter is . + public IEnumeratorFromNext(TIEnum enumObj, TryGetNext next, Action reset) + { + if (enumObj == null || next == null || reset == null) throw new ArgumentNullException(); + ienum = enumObj; + this.next = next; + this.reset = reset; + reset(ienum); + } + + /// + /// Gets the object in the collection to which the enumerator is pointing. + /// + public virtual TItem Current => current; + + /// + /// Gets the object in the collection to which the enumerator is pointing. + /// + object IEnumerator.Current => Current; + + /// Disposes of the Enumerator object. + public virtual void Dispose() + { + ienum = null; + current = default; + } + + /// Moves the enumerator index to the next object in the collection. + /// + public virtual bool MoveNext() + { + try { return next(ienum, out current); } + catch { return false; } + } + + /// Resets the enumerator index to the beginning of the collection. + public virtual void Reset() + { + current = default; + reset(ienum); + } + } + /// /// Creates an enumerable class from a get next method in the form of HRESULT Next(uint, TItem[], out uint) and a reset method. Useful if /// a class doesn't support or like some COM objects. @@ -126,7 +206,7 @@ namespace Vanara.Collections public class IEnumFromNext : IEnumerable { /// The next function delegate. - protected TryGetNext next; + protected TryGetNext next; /// The reset function delegate. protected Action reset; @@ -134,7 +214,7 @@ namespace Vanara.Collections /// Initializes a new instance of the class. /// The method used to try to get the next item in the enumeration. /// The method used to reset the enumeration to the first element. - public IEnumFromNext(TryGetNext next, Action reset) + public IEnumFromNext(TryGetNext next, Action reset) { if (next == null || reset == null) throw new ArgumentNullException(); this.next = next; @@ -144,13 +224,6 @@ namespace Vanara.Collections /// Initializes a new instance of the class. protected IEnumFromNext() { } - /// - /// Delegate that gets the next value in an enumeration and returns true or returns false to indicate there are no more items in the enumeration. - /// - /// The value, on success, of the next item. - /// true if an item is returned, otherwise false. - public delegate bool TryGetNext(out TItem value); - /// Returns an enumerator that iterates through the collection. /// A that can be used to iterate through the collection. public IEnumerator GetEnumerator() => new Enumerator(this);