Will enumerator keep its collection alive

J

JohnS

Hi there,

Can someone confirm my understanding of the following. Given a function that
creates and populates a "List<T>" on-the-fly, or any native .NET collection
for that matter, and then returns "List<T>.GetEnumerator()", will that
enumerator keep the list itself alive? Or can the list be GC'd and the
enumerator then points to junk. Presumably this won't happen since the
enumerator will either keep it alive via some internal pointer, or it will
cache the data itself in theory (ok, not likely in reality but the idea is
that it can always enumerate the data even it doesn't keep the collection
alive). Can someone confirm this. Thanks.
 
P

Peter Duniho

JohnS said:
Hi there,

Can someone confirm my understanding of the following. Given a function that
creates and populates a "List<T>" on-the-fly, or any native .NET collection
for that matter, and then returns "List<T>.GetEnumerator()", will that
enumerator keep the list itself alive? Or can the list be GC'd and the
enumerator then points to junk. Presumably this won't happen since the
enumerator will either keep it alive via some internal pointer, or it will
cache the data itself in theory (ok, not likely in reality but the idea is
that it can always enumerate the data even it doesn't keep the collection
alive). Can someone confirm this. Thanks.

You could have easily tested it yourself. But, no…you don't have to
worry about the underlying collection being collected. An IEnumerator
implementation necessarily needs a reference to the data being
enumerated, and so if the IEnumerator is reachable, so too must the data
being enumerated.

Note that that does not necessarily mean that the public collection
class itself will remain reachable. The IEnumerator implementation in
theory could reference only the data within. But if that were the case,
that would mean that the IEnumerator doesn't need to access the public
collection, and so the public collection being GC'ed would have no
effect on the IEnumerator implementation.

For example:

class Test : IEnumerable
{
private int[] _data = { 1, 2, 3 };

public IEnumerator GetEnumerator()
{
return _data.GetEnumerator();
}
}

This class returns an enumerator that has no references to the Test
instance itself. Thus, the Test instance could be collected. But, the
enumerator also doesn't need the Test instance. It only cares about the
int[] instance that was inside, and _that_ instance remains reachable,
and thus not collectable.

In most cases, however, the IEnumerator is either actually a member of
the public collection class, or will retain a reference to it. Making
the point doubly moot. :)

The whole point of the way a GC system works is that objects that are
reachable _by any means_ cannot be collected. It is impossible for code
somewhere to access "junk" that has been collected, because by
definition if it could do that, the "junk" was actually reachable
(that's what reachable means…code can reach it!) and wouldn't have been
collected.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top