This is a follow-up to my post, Is this a correct implementation of a concurrent observable collection?.
In that post I have a custom class that implements a generic concurrent observable list, including an implementation of IEnumerable<T>.GetEnumerator(). This was the original code:
public IEnumerator<T> GetEnumerator()
{
var localSnapshot = _snapshot; //create local variable to protect enumerator, if class member (_snapshot) should be changed/replaced while iterating
return ((IEnumerable<T>)localSnapshot).GetEnumerator();
}
With _snapshot being a private Array field that is rebuilt using a lock() whenever the actual inner collection (List<T> _list) is modified.
But now I think the localSnapshot variable is not required at all, the code should be:
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)_snapshot).GetEnumerator();
}
Because localSnapshot is simply assigned a reference to the same address that _snapshot references. GetEnumerator doesn't care (and cannot tell) which variable was used (and will for its own use, of course, create yet another variable that references the same array).
If my above assumption is correct, I wonder, if the compiler would optimize the variable away? Then the resulting code would be identical. Or, if not: could copying the reference theoretically even be "harmful", because the copy will be less up-to-date than it could be (another thread could refresh _snapshot after the copy was made, but before GetEnumerator is called)? And, is this "side-effect" the reason the compiler does not optimize the code - because optimizations are to be "side-effect-free"?