Я немного изучаю программирование функций, и мне интересно:
1) Чист ли мой метод расширения ForEach
? То, как я это называю, кажется, нарушает правило «не связываться с передаваемым объектом», верно?
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach ( var item in source )
action(item);
}
static void Main(string[] args)
{
List<Cat> cats = new List<Cat>()
{
new Cat{ Purring=true,Name="Marcus",Age=10},
new Cat{ Purring=false, Name="Fuzzbucket",Age=25 },
new Cat{ Purring=false, Name="Beanhead",Age=9 },
new Cat{Purring=true,Name="Doofus",Age=3}
};
cats.Where(x=>x.Purring==true).ForEach(x =>
{
Console.WriteLine("{0} is a purring cat... purr!", x.Name);
});
// *************************************************
// Does this code make the extension method impure?
// *************************************************
cats.Where(x => x.Purring == false).ForEach(x =>
{
x.Purring = true; // purr,baby
});
// all the cats now purr
cats.Where(x=>x.Purring==true).ForEach(x =>
{
Console.WriteLine("{0} is a purring cat... purr!", x.Name);
});
}
public class Cat {
public bool Purring;
public string Name;
public int Age;
}
2) Если это нечисто, это плохой код? Лично я считаю, что код выглядит чище, чем старый foreach ( var item in items) { blah; }
, но я беспокоюсь, что, поскольку он может быть нечистым, он может создать беспорядок.
3) Будет ли плохой код, если он вернет IEnumerable<T>
вместо void
? Я бы сказал, что пока он нечист, да, это будет очень плохой код, поскольку он будет поощрять создание цепочки чего-то, что изменит цепочку. Например, это плохой код?
// possibly bad extension
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach ( var item in source )
action(item);
return source;
}