Exceptions related to IEnumerator
-
According to MSDN, methods of IEnumerator are expected to throw an exception if the enumerated collection has been modified For Example,
List<int> list = new List<int>(); list.Add(1); IEnumerator enumerator = list.GetEnumerator(); enumerator.Reset(); // It' ok to reset the enumerator list.Add(2); // The collection is modified. enumerator.Reset(); // Now InvalidOperationException is raised
When implementing the methods of IEnumerator in our own class, we should have them throw the exception if the collection is modified. Now I have a class :class MyEnumerator:IEnumerator{ int[] integers; /// /// Methods /// public void Reset(){ } }
How to implement Reset in an elegant way, so that I can throw an InvalidOperationException when Reset is called after integers are modified? Thank you! :-O -
According to MSDN, methods of IEnumerator are expected to throw an exception if the enumerated collection has been modified For Example,
List<int> list = new List<int>(); list.Add(1); IEnumerator enumerator = list.GetEnumerator(); enumerator.Reset(); // It' ok to reset the enumerator list.Add(2); // The collection is modified. enumerator.Reset(); // Now InvalidOperationException is raised
When implementing the methods of IEnumerator in our own class, we should have them throw the exception if the collection is modified. Now I have a class :class MyEnumerator:IEnumerator{ int[] integers; /// /// Methods /// public void Reset(){ } }
How to implement Reset in an elegant way, so that I can throw an InvalidOperationException when Reset is called after integers are modified? Thank you! :-OHi, I have not done this yet, but here is an idea: - in the object you want to be able to enumerate, keep a generation counter that starts at zero and gets incremented every time you modify the collection (hence Add, Remove, Clear, ... all contain "generation++;") - in the enumerator hold a copy of the generation counter, equal to the collection's generation at the moment you create the enumerator - in each enumerator method compare enumerator generation with collection generation; when unequal, throw the exception. Refinement: to reduce the risk of generation overflow, rather than incrementing all the time, your collection could keep two generation values (current and next), that both start at zero. Each modification sets "generation=nextGeneration;", and each getEnumerator does "generation=nextGeneration++;" hence the generation can only increase if an enumerator has been requested. :)
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.
-
Hi, I have not done this yet, but here is an idea: - in the object you want to be able to enumerate, keep a generation counter that starts at zero and gets incremented every time you modify the collection (hence Add, Remove, Clear, ... all contain "generation++;") - in the enumerator hold a copy of the generation counter, equal to the collection's generation at the moment you create the enumerator - in each enumerator method compare enumerator generation with collection generation; when unequal, throw the exception. Refinement: to reduce the risk of generation overflow, rather than incrementing all the time, your collection could keep two generation values (current and next), that both start at zero. Each modification sets "generation=nextGeneration;", and each getEnumerator does "generation=nextGeneration++;" hence the generation can only increase if an enumerator has been requested. :)
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.
-
Yeah, I see, thanks for your neat idea. Then my collection class has to expose an extra property, say Generation{get{}}, right?
SeeBees wrote:
expose an extra property, say Generation{get{}},
Not really, if your Collection inherits from an existing one, you can implement your own
public override IEnumerator GetEnumerator()
just like the original collection did. :)Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips: - before you ask a question here, search CodeProject, then Google; - the quality and detail of your question reflects on the effectiveness of the help you are likely to get; - use PRE tags to preserve formatting when showing multi-line code snippets.