У мене є такий метод розширення:
public static IEnumerable<T> Apply<T>(
[NotNull] this IEnumerable<T> source,
[NotNull] Action<T> action)
where T : class
{
source.CheckArgumentNull("source");
action.CheckArgumentNull("action");
return source.ApplyIterator(action);
}
private static IEnumerable<T> ApplyIterator<T>(this IEnumerable<T> source, Action<T> action)
where T : class
{
foreach (var item in source)
{
action(item);
yield return item;
}
}
Він просто застосовує дію до кожного елемента послідовності перед поверненням.
Мені було цікаво, чи слід застосувати Pure
атрибут (від анотацій Resharper) до цього методу, і я можу побачити аргументи «за» і «проти».
Плюси:
- строго кажучи, є чистим; просто виклик його в послідовності не змінює послідовність (вона повертає нову послідовність) або не вносить будь-яких змін, що спостерігаються
- називати його без використання результату, очевидно, є помилкою, оскільки це не має ефекту, якщо не буде перерахована послідовність, тому я хотів би, щоб Решарпер попередив мене, якщо це зробити.
Мінуси:
- навіть якщо
Apply
сам метод чистий, перерахування отриманої послідовності буде зробити спостерігаються зміни стану (яка є точкою методи). Наприклад,items.Apply(i => i.Count++)
буде змінювати значення елементів кожного разу, коли він перераховується. Тож застосування атрибута Pure, ймовірно, вводить в оману ...
Як ти гадаєш? Потрібно застосувати атрибут чи ні?