What is the best way to make extended IEnumerator safe?

  • Thread starter Thread starter Daniel O'Connell
  • Start date Start date
D

Daniel O'Connell

Sasha said:
Hi,

I am extending standard IEnumerator, and I was just wondering what is the
best way to make enumarator safe? What do I mean by safe? Detect deletes and
all...
My idea is to have private Guid state field in the collection, and every
time something is inserted or deleted from the collection, I will just
change the guid. Enumerator will just have to compare the guid received in
the begging to the current one. If they are different, the collection has
changed.

That would work, but would probably be overkill. It would be simple enough
just to maintain an Int32 or Int64 version counter and increment it every
time the collection changes, store the value when the IEnumerator is created
and check against it. It would probably be faster and less troublesome, just
a version++; \ version = version+1 to update(depending on your language, not
sure if vb.net has an increment operator...). Its not likely your collection
is going to change enough to overflow an Int32, let alone an Int64.
 
Hi,

I am extending standard IEnumerator, and I was just wondering what is the
best way to make enumarator safe? What do I mean by safe? Detect deletes and
all...
My idea is to have private Guid state field in the collection, and every
time something is inserted or deleted from the collection, I will just
change the guid. Enumerator will just have to compare the guid received in
the begging to the current one. If they are different, the collection has
changed.

What are your thought on this?

Thank you,
Sasha
 
Sasha said:
How would I pass it from the collection to the Enumerator?
Simpilest method would be a readonly property, but that is only elegent if
other classes could have a use for the version.

Have you considered an inner class? I apologize for posting this in C# code,
I don't konw enough VB to whip this up readily, as I'm not sure about inner
class syntax and the like. This code will also not compile, it is really
just a sample showing the basis of what i mean.

public class MyClass : IEnumerable
{

public IEnumerator GetEnumerator() {

}
int version;
//define a class internally to yoru colelction that implements IEnumerator
class MyClassEnumerator : IEnumerator
{
public myClassEnumerator(MyClass class) {
//should let you access private members of MyClass
baseVersion = class.version;
this.class = class;
}
MyClass class;
int baseVersion;
public object Current {
get {
if (class.Version != baseVersion)
//throw your exception;
return <getobject>;
}
}
}
}
 
How would I pass it from the collection to the Enumerator?

I can expose it as a readonly property, but it is not very elegant...
I wish .Net had "friend" keyword, just like C++....
 
Steve,
However VB.NET Friend <> C++ Friend!

In VB.NET Friend means that the property is visible to every one in the
assembly.

In C++ Friend means that just this one specific class is my friend, making
it significantly more intimate.

Notice that Sasha stated "had "friend" keyword, just like C++...."

Hope this helps
Jay
 
Hi Sasha,

You want a safe IEnumerator, which makes sense - sort of. I'm curious as
to what you want this for.

If the Enumerator detects that a collection has been changed, it could be
due to a bug in the code (the Collection isn't supposed to be changed), or due
to external 'interference' (eg another thread). In these cases I guess you'd
want an Exception.

It could be intended behaviour, eg deleting certain items from the
Collection. In this case you could argue that ISafeEnumerator shouldn't be
used. But what if I wanted it to gracefully deal with this and 'skip' the
deletions? Is this part of the plan?

Basically - What's it all about? ;-)

Curiously,
Fergus
 
Public Class [MyClass]
Implements IEnumerable 'ToDo: Add Implements Clauses for implementation
methods of these interface(s)


Public Function GetEnumerator() As IEnumerator
End Function 'GetEnumerator
Private version As Integer
_
'define a class internally to yoru colelction that implements IEnumerator
Class MyClassEnumerator
Implements IEnumerator 'ToDo: Add Implements Clauses for
implementation methods of these interface(s)

Public Sub New(__unknown As [MyClass])
If (True) Then '
'ToDo: Error processing original source shown below
'
'
'--------------------------------------^--- Syntax error:
'identifier' expected
'
'ToDo: Error processing original source shown below
'
'
'-------------------------------------------^--- expression
expected
'should let you access private members of MyClass
baseVersion = __unknown
__unknown.version '
'ToDo: Error processing original source shown below
'
'
'-------------------^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'------------------------^--- expression expected
Me.__unknown
__unknown = __unknown '
'ToDo: Error processing original source shown below
'
'
'----------^--- Syntax error: 'identifier' expected
'
'ToDo: Error processing original source shown below
'
'
'----------------^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'------------------^--- expression expected
End If
'
'ToDo: Error processing original source shown below
'
'
'---------^--- Syntax error: ';' expected
Dim baseVersion As Integer
Dim Current As Object
If (True) Then '
'ToDo: Error processing original source shown below
'
'
'-^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'-----------------------^--- Syntax error: ';' expected
If (True) Then '
'ToDo: Error processing original source shown below
'
'
'---------^--- Syntax error: ';' expected
If __unknown Then '
'ToDo: Error processing original source shown below
'
'
'-------------^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'------------------^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'-----------------------------------------^--- Syntax error:
';' expected
End If
__unknown.Version <> baseVersion
'throw your exception;
Return __unknown < getobject > __unknown '
'ToDo: Error processing original source shown below
'
'
'----------------^--- expression expected
'
'ToDo: Error processing original source shown below
'
'
'---------------------------^--- expression expected
'
'ToDo: Error processing original source shown below
'System.Char[]
'^--- Syntax error: '}' expected
End If
End If
End Sub 'New
End Class 'MyClassEnumerator
End Class '[MyClass]
 
That's exactly what I meant by safe Enumerator. If the collection changes,
I should throw an exception. Just like it happens in standard enumerators.

I just wanted to know the best way to track the state of the collection. I
could have checked the count every time I do MoveNext, but this is a slight
probability that one item was inserted and another one was removed.

So anyways, you are right about this. And that is what I meant by "safe"
enumerator. If a collection changes during enumeration, I need throw an
exception.

Thank you very much for your anwer.

Take Care,
Sasha
 
Back
Top