J'apprends un peu sur la programmation des fonctions, et je me demande:Est-ce que cette méthode d'extension C# est impure et si oui, un mauvais code?
1) Si ma méthode d'extension ForEach
est pure? La façon dont je l'appelle semble violer le "ne pas jouer avec l'objet qui se passe", non?
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) Si c'est impur, est-ce mauvais code? Personnellement, je pense que cela rend le code plus propre que le vieux foreach (var item in items) { blah; }
, mais je crains que, comme il pourrait être impur, il pourrait faire un gâchis.
3) Serait-ce un mauvais code s'il renvoyait IEnumerable<T>
au lieu de void
? Je dirais que tant que c'est impur, oui ce serait un très mauvais code car cela encouragerait à enchaîner quelque chose qui modifierait la chaîne. Par exemple, est-ce mauvais code?
// 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;
}
Excellente réponse. –