2016-06-19 4 views
0

У меня есть этот код:C# событие не может вызвать анонимный метод с правильным значением аргумента

for (int i = 0; i < 7; ++i) 
    Roption.DropDownItems.Add(string.Concat("Item &", i), null, delegate { Reset(i); }); 

где Reset() вызывается, когда элемент выпадающих кнопок.

Проблема заключается в том, что независимо от того, который нажал выпадающий элемент, аргумент, передаваемый Reset 7 (значение i после того, как цикл завершается), а не значение i, когда функция вызывается Roption.DropDownItems.Add. Что вызывает такое поведение и как оно может быть исправлено? (Я не хочу, чтобы жесткий код с 0 по 6 в семи других идентичных заявлениях).

+1

Сделайте копию переменной 'i' как этот' i1 = i' и передать 'i1' сбросить метод вместо ... http://stackoverflow.com/questions/271440/captured-variable -in-a-loop-in-c-sharp –

+0

Это работает, спасибо! – limits

ответ

2

Ваша проблема заключается в том, что при создании делегатов в цикле все объекты будут передаваться по ссылке. Это означает, что независимо от того, являются ли они объектами типа значения или ссылочного типа, они все равно будут передаваться по ссылке.

Что это значит для вашего кода? Ну, поскольку цикл итерации проходит, все вызовы метода Reset, имеющие копию i, имеют ссылку на один и тот же. Таким образом, по мере увеличения значения i увеличивается значение для каждой отдельной ссылки.

Closures Explained