views:

162

answers:

4

Is it possible to serialize a method containing yield statements (or a class that contains such a method) such that when you rehydrate the class, the internal state of the generated iterator is retained?

+4  A: 

Internally, yield statement is transformed to state machine implemented as class that implements IEnumerator interface. It allows to iterate throught resultset using multiple foreach statements at the same time. That class is not visible to your code, it is not marked as serializable.

So, answer is no, it is not possible. But, you can implement desired enumerator by itself, but it requires more labor than yield.

STO
I would say this is not entirely correct. It is possible, but perhaps strongly not recommended.
Joseph Kingry
+1  A: 

Just make sure that just before you call yield, that you save state (i.e., the iterators position) in a serializable field (the location field, or whatever you call it). Then, when the class is deserialized, simply continue where you left off, using the location field.

But, when will this be useful? Do you plan to serialize objects in the middle of a foreach loop? Maybe you make it a lot easier if you give you class a SetIteratorPosition() method, which defaults to the current position. It's clearer than adding side effects to existing well defined behavior (yield) and everyone'll understand that IteratorPosition can be saved.

Note: methods cannot be serialized. You serialize data, i.e., properties and fields.

Abel
+1  A: 

Yes. Any method that returns an IEnumerable can have it's own code for yield return whatever you tell it to. If you serialize the internal state of your object as to what it was iterating and how far it got, then you can reload that state at some future time, and continue the enumeration right where you left off.

uosɐſ
+4  A: 
Joseph Kingry
+1 very interesting!
Abel