Это продолжение моего поста, Является ли это правильной реализацией параллельной наблюдаемой коллекции? .
В этом посте у меня есть собственный класс, который реализует универсальный параллельныйнаблюдаемый список, включая реализацию IEnumerable<T>.GetEnumerator()
.Это был оригинальный код:
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();
}
С _snapshot
, являющимся частным Array
полем, которое перестраивается с помощью lock()
всякий раз, когда изменяется фактическая внутренняя коллекция (List<T> _list
).
Но теперь я думаю, что переменная localSnapshot
вообще не требуется, код должен быть:
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)_snapshot).GetEnumerator();
}
Поскольку localSnapshot
просто назначается ссылка на тот же адрес, на который ссылается _snapshot
,GetEnumerator
не волнует (и не может сказать), какая переменная использовалась (и, конечно, для ее собственного использования создаст еще одну переменную, которая ссылается на тот же массив).
Если мое предположение выше верноИнтересно, если бы компилятор оптимизировал переменную?Тогда полученный код будет идентичен.Или, если нет: теоретически копирование ссылки может быть «вредным», потому что копия будет менее актуальной, чем могла бы быть (другой поток мог обновить _snapshot
после того, как копия была сделана, но до GetEnumerator
называется)?И является ли этот «побочный эффект» причиной, по которой компилятор не оптимизирует код - потому что оптимизации должны быть «без побочных эффектов»?