Я рассматриваю язык сценариев как что-либо не требование откровенного тяжеловеса, чувствующего, что 'компиляция' ступает. Основная функция с точки зрения программистов: Вы редактируете код и выполняете его сразу же.
Таким образом я расценил бы JavaScript и PHP как языки сценариев, тогда как ActionScript 3 / Flex не действительно.
Причина предупреждения что внутри цикла вы можете обращаться к изменяющейся переменной. Однако «исправление» на самом деле ничего не делает для вас в этом контексте, не являющемся циклом.
Представьте, что у вас есть цикл FOR, и if находится внутри него, а объявление строки - вне его. В этом случае ошибка будет правильно определять проблему получения ссылки на что-то нестабильное.
Пример того, чего вы не хотите:
string acctStatus
foreach(...)
{
acctStatus = account.AccountStatus[...].ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
}
Проблема в том, что замыкание захватывает ссылку на acctStatus, но каждая итерация цикла будет изменять это значение. В в том случае было бы лучше:
foreach(...)
{
string acctStatus = account.AccountStatus[...].ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
}
Поскольку контекст переменной - это цикл, новый экземпляр будет создаваться каждый раз, потому что мы переместили переменную внутрь локального контекста (цикл for).
Рекомендация звучит как ошибка в синтаксическом анализе этого кода Resharper. Однако во многих случаях это серьезная проблема (например, в первом примере, где ссылка изменяется, несмотря на то, что она зафиксирована в замыкании).
Мое практическое правило: в случае сомнений сделайте локальный.
Здесь это реальный пример, который меня укусил:
menu.MenuItems.Clear();
HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);
for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
{
HistoryItem crumb = crumbs[i];
NodeType type = nodeType; //Local to capture type.
MenuItem menuItem = new MenuItem(crumb.MenuText);
menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
menu.MenuItems.Add(menuItem);
}
Обратите внимание, что я фиксирую тип NodeType local, обратите внимание на nodeType и HistoryItem crumb.ItemGuid, а не crumbs [i] .ItemGuid. Это гарантирует, что в моем закрытии не будет ссылок на элементы, которые будут изменены.
Перед использованием локальных переменных события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.
Рекомендация звучит как ошибка при анализе этого кода Resharper. Однако во многих случаях это серьезная проблема (например, в первом примере, где ссылка изменяется, несмотря на ее фиксацию в закрытии).
Мое практическое правило: в случае сомнений сделайте локальный.
Здесь это реальный пример, который меня укусил:
menu.MenuItems.Clear();
HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);
for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
{
HistoryItem crumb = crumbs[i];
NodeType type = nodeType; //Local to capture type.
MenuItem menuItem = new MenuItem(crumb.MenuText);
menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
menu.MenuItems.Add(menuItem);
}
Обратите внимание, что я фиксирую тип NodeType local, обратите внимание на nodeType и HistoryItem crumb.ItemGuid, а не crumbs [i] .ItemGuid. Это гарантирует, что в моем закрытии не будет ссылок на элементы, которые будут изменены.
Перед использованием локальных переменных события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.
Рекомендация звучит как ошибка при анализе этого кода Resharper. Однако во многих случаях это серьезная проблема (например, в первом примере, где ссылка изменяется, несмотря на ее фиксацию в закрытии).
Мое практическое правило: в случае сомнений сделайте локальный.
Здесь это реальный пример, который меня укусил:
menu.MenuItems.Clear();
HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);
for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
{
HistoryItem crumb = crumbs[i];
NodeType type = nodeType; //Local to capture type.
MenuItem menuItem = new MenuItem(crumb.MenuText);
menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
menu.MenuItems.Add(menuItem);
}
Обратите внимание, что я фиксирую тип NodeType local, обратите внимание на nodeType и HistoryItem crumb.ItemGuid, а не crumbs [i] .ItemGuid. Это гарантирует, что в моем закрытии не будет ссылок на элементы, которые будут изменены.
Перед использованием локальных переменных события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.
где ссылка меняется, несмотря на то, что она фиксируется в закрытии).Мое практическое правило: в случае сомнений делайте локальную.
Вот пример из реального мира, который меня укусил:
menu.MenuItems.Clear();
HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);
for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
{
HistoryItem crumb = crumbs[i];
NodeType type = nodeType; //Local to capture type.
MenuItem menuItem = new MenuItem(crumb.MenuText);
menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
menu.MenuItems.Add(menuItem);
}
Обратите внимание, что я фиксирую тип NodeType локальный, обратите внимание на nodeType и HistoryItem crumb.ItemGuid, а не crumbs [i] .ItemGuid. Это гарантирует, что в моем закрытии не будет ссылок на элементы, которые будут изменены.
Перед использованием локальных переменных события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.
где ссылка меняется, несмотря на то, что она фиксируется в закрытии).Мое практическое правило: в случае сомнений делайте локальную.
Вот пример из реального мира, который меня укусил:
menu.MenuItems.Clear();
HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);
for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
{
HistoryItem crumb = crumbs[i];
NodeType type = nodeType; //Local to capture type.
MenuItem menuItem = new MenuItem(crumb.MenuText);
menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
menu.MenuItems.Add(menuItem);
}
Обратите внимание, что я фиксирую тип NodeType локальный, обратите внимание на nodeType и HistoryItem crumb.ItemGuid, а не crumbs [i] .ItemGuid. Это гарантирует, что в моем закрытии не будет ссылок на элементы, которые будут изменены.
Перед использованием локальных переменных события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.
события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал. события будут запускаться с текущими значениями, а не с полученными значениями, которые я ожидал.