Как вы относитесь к такому коду?
Оставим в стороне аргументацию за и против лямбда-функций. Основное нарекание, разумеется, вызывает метод ToList(), используемый только для того, чтобы получить доступ к вожделенному методу ForEach(), отсутствующему в EntitySet, дабы получить красивый и понятный, с точки зрения разработчика, код, умещающийся в одну строку.
* This source code was highlighted with Source Code Highlighter.
private EntitySet persons;
public void SomeMethod()
{
/// ...
persons.ToList().ForEach(person => person.Id = Guid.NewGuid());
/// ...
}
Оставим в стороне аргументацию за и против лямбда-функций. Основное нарекание, разумеется, вызывает метод ToList(), используемый только для того, чтобы получить доступ к вожделенному методу ForEach(), отсутствующему в EntitySet, дабы получить красивый и понятный, с точки зрения разработчика, код, умещающийся в одну строку.
Предложение заменить "вожделенный" ForEach() следующим образом, аргументированное тем, что не тратятся ресурсы на создание List'а (как память, так и процессорное время на конструкцию и последующую сборку мусора), опровергается как нецелесообразное.
* This source code was highlighted with Source Code Highlighter.
foreach(var person in persons)
person.Id = Guid.NewGuid();
Аргументация (приблизительная): «.NET для того и создан, чтобы о таких вещах не задумываться. Я смотрел Reflector'ом исходники .NET'а, там о производительности мало задумываются. Нет смысла оптимизировать кусок кода со сложностью o(), когда есть столь же часто вызываемый кусок кода со сложностью O(). Поэтому, если данный кусок кода не является узким местом, то создать объект наподобие List() и тут же отправить его на съедение сборщику мусора - это нормально. И вообще, если нужно оптимизировать в таких мелочах, то нужно отказаться от ASP.NET, и писать на C++».
На мой, субъективный взгляд, сомнительной оптимизацией (но как ни крути, а все же оптимизацией) можно считать требование отказаться от лямбда-функций (вызов метода ForEach для коллекции из N элементов - N+1 вызовов функций, на которых тоже можно сэкономить процессорные команды). А вот отказ от создания мимолетного объекта можно считать оптимизацией существенной, независимо от сложности других участков кода. Другими словами, первый кусок кода является сам по себе плохо пахнущим, и от таких необходимо избавляться.
Допустимым можно считать создание недостающего екстеншн-метода для повторного использования (при непреодолимой любви к лямбда-функциям):
* This source code was highlighted with Source Code Highlighter.
public static void ForEach(this IEnumerable array, Action action)
{
foreach (var item in array)
action(item);
}
public void SomeMethod()
{
/// ...
persons.ForEach(person => person.Id = Guid.NewGuid());
/// ...
}
Непревзойденным (по соотношению наглядность/цена) по-прежнему остается "классический" foreach, а создание заведомо выкидываемых объектов в качестве синтаксического сахара (в этой и других подобных ситуациях) следует классифицировать как быдлокод?
И еще один подобный вопрос в продолжение.
1 комментарий:
Ну, в .NET 4.0 для параллельных операторов есть свой класс и выглядят они как Parallel.ForEach(); и ничего :)
А так да, я за то, чтобы написать свой экстеншн-метод, чем лишний раз конвертировать туда-сюда коллекции.
Отправить комментарий