Дело было так. Был словарь(Dictionary) в котором содержались Id объектов и дополнительная информация. Был также массив других объектов, в котором у объектов с Id из словаря нужно было подписаться на событие. Обработчик простой, поэтому решил прям в методе создать делегат. Тело цикла вышло что-то вроде этого:
CalcHandler calc = delegate(object sender,CalcEventArgs e){
e.NewValue += e.BaseValue * pair.Value;
};
obj[pair.Key].Calc += calc;
e.NewValue += e.BaseValue * pair.Value;
};
obj[pair.Key].Calc += calc;
Однако когда написал тесты, выяснилось, что в качестве pair.Value всегда выступает последнее ее значение в этом цикле! Попробовал добавить промежуточные переменные, но оптимизация все съела и толку не было. В итоге пришлось переписать цикл на for() в результате чего все отлично заработало.
Так что товарищи, хорошенько подумайте, прежде чем использовать foreach! Я не призываю от него отказываться, ведь должна же быть и от него польза :) но прежде чем использовать - обдумайте все возможные варианты, ведь если нет такого рода тонкостей, то возможно в будущем придется изменять код, а переписывать цикл, особенно если он порос разными хитростями, ой как лениво...
3 комментария:
мне кажется тут проблема не в foreach, а в неправильном архитектурном подходе.
Архитектура это дело такое, что идеального варианта не найти. Поэтому практически каждую новую проблему или нестыковку можно отнести к проблеме в архитектуре:)
А пост был опубликован, чтобы показать интересную особенность foreach, и изучать, где тут была ошибка, я думаю бессмысленно.
Наткнулся на статью в MSDN по этому поводу.
http://blogs.msdn.com/ruericlippert/archive/2009/11/12/9983705.aspx
Отправить комментарий