2010-04-07 4 views
1

меня последняя ReSharper 5.0 сборки (1655), где я столкнулся с рекомендации «Доступ к модифицированному закрытия» на следующий код:Доступ к модифицированному закрытию, это ошибка ReSharper?

var now = new DateTime(1970, 1, 1); 
var dates = new List<DateTime>(); 
dates.Where(d => d > now); 
... 
now = new DateTime(); 

и now внутри лямбда-выражения подчеркнут с предупреждением.

Я уверен, что это ошибка ReSharper, но так ли это?

EDIT: Я должен был проверить лучше, было назначено now позже в коде.

EDIT 2 Jon Скит answer ниже довольно многое ответов, но как насчет следующего:

var query = dates.Where(d => d > now).ToList(); 

не должен это решить проблему немедленно выполнения запроса?

+2

Буквально только на этом коде? Не назначать «сейчас» после этих строк? –

+0

@ Jon Skeet Вы правы, было задание несколько строк вниз! Я изменю вопрос. –

ответ

4

Право, теперь вы изменили вопрос, это имеет смысл. Вы модификации переменной, используемой в закрытии - что может привести к неожиданным результатам:

var now = new DateTime(1970, 1, 1); 
var dates = new List<DateTime>(); 
var query = dates.Where(d => d > now); 
... 
now = new DateTime(1990, 1, 1); 
foreach (DateTime date in query) 
{ 
    // This will only see dates after 1990, not after 1970 
    // This would confuse many developers. 
} 

На самом деле, это не только вопрос о том, когда начинается запрос - вы можете изменить его в то время как итерация по результатам:

var now = new DateTime(1970, 1, 1); 
var dates = new List<DateTime>(); 
var query = dates.Where(d => d > now); 
... 
foreach (DateTime date in query) 
{ 
    now = date; 
    Console.WriteLine(date); 
} 

Это даст строго возрастающую последовательность дат ... снова, несколько запутанную.

R # абсолютно прав, чтобы предупредить об этом, ИМО. Может быть иногда быть полезным - но его следует использовать с большой осторожностью.

+0

Что делать, если я вызываю 'ToList()', не следует ли это немедленно выполнить запрос, тем самым предотвращая эту ситуацию? –

+0

@hmemcpy: Да, это так. –

+0

Но предупреждение остается, возможно, это может быть ошибка ReSharper по-прежнему ... –

0

Нет, это нерешенное мышление о том, что вы изменяете содержимое коллекции, перебирая ее, dates скорее всего. Вы можете смело игнорировать это.

+0

Поскольку 'now' является захваченной переменной, любые изменения в ней до того, как будет оцениваться запрос, скорее всего, приведут к другому результату, чем ожидалось, что и пытается показать R #. –

+0

-1: он не может смело игнорировать его – ANeves

+0

hmm, похоже, вопрос был изменен на код, где он использует цикл –

1

Что ReSharper предупреждает вас о том, что значение now фиксируется в выражении лямбда и не является значением, которое, по вашему мнению, является, когда выполняется лямбда.

Чтобы решить проблему, необходимо присвоить значение now локальной переменной, прежде чем использовать его:

var now = new DateTime(1970, 1, 1); 
var dates = new List<DateTime>{new DateTime(2001, 12, 12)}; 
DateTime localNow = now; 
dates.Where(d => d > localNow); 

now = new DateTime(2003, 12, 12); 

Если вы хотите узнать больше, то ReSharper форум имеет post на нем, которая включает в себя несколько ссылок с дальнейшим объяснением.

Смежные вопросы