Удаляет ли ToList () необходимость исправления предупреждения «Доступ к измененному закрытию»? - PullRequest
2 голосов
/ 30 ноября 2011

У меня есть следующий код:

foreach (var parent in parents)
{
    var children = data.Find<Order>(x=>x.ParentOrderId==parent.OrderId).ToList();
    // Do stuff with the children variable
}

Resharper говорит мне, что у меня есть проблема с доступом к измененному закрытию для родительской переменной.Но разве вызов ToList () не означает, что он будет оценен сразу?

Означает ли это, что это необходимо?

foreach (var parent in parents)
{
    var parentClosure = parent;
    var children = data.Find<Order>(x=>x.ParentOrderId==parentClosure.OrderId).ToList();
    // Do stuff with the children variable
}

Ответы [ 3 ]

8 голосов
/ 30 ноября 2011

Именно поэтому «Доступ к измененному закрытию» - это всего лишь предупреждение, а не ошибка. В принципе, пока это замыкание (любая ссылка на него) не может избежать одной итерации тела цикла, у вас все в порядке.

И поскольку, как вы упомянули, .ToList() оценивает IEnumerable, удерживающий замыкание, вы в порядке, и это предупреждение действительно безвредно, и вы можете смело подавлять его комментарием.

Для того чтобы ReSharper знал, когда это предупреждение серьезное, он должен не только выполнить анализ аварийного сброса на закрытии, он также должен знать, как Find<T> и .ToList() ведут себя в отношении удержания закрытия. Это, вероятно, не произойдет в ближайшее время.

4 голосов
/ 30 ноября 2011

ReSharper не может сказать, что Find не хранит лямбду где-то глобально для последующего использования, поэтому в любом случае выдает предупреждение.

3 голосов
/ 30 ноября 2011

Это проблема, только если вы вызываете лямбда-выражение после изменения переменной parent - после этой итерации цикла.

Если вы вызываете ToList(), лямбда-выражение используется только внутри ToList()call.

Если вы не звоните ToList(), лямбда-выражение используется каждый раз, когда вы перечисляете запрос LINQ.
Если вы никогда не будете использовать этот запрос позже, вам не понадобится ToList().

...