I love lambdas, and functional programming etc. But sometimes I wonder if I take it too far..
public static T With<T>(this T source, Action<T> action)
{
action(source);
return source;
}
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
return source.Select(x => x.With(action));
}
thoughts?
UPDATE
Some good points, some I agree with, some I don't, but a few details:
I understand that Linq
may not be intended to handle side effects, especially since List.ForEach
returns void, however I disagree that functional programming can't contain side effects, a monad is simply a chunk of code to execute for a given structure.
The ForEach
and With
extensions, are meant to be a syntactic sugar. Perhaps the name is poorly chosen, and it should be something like OnEnumerate
, however I wonder if this could get confusing down the line, as its whole point is to invoke side effects at that particular point in the expression, and this could occur multiple times, perhaps I should stick with my With
convention and do WithEach
.
The comments about using Select
internally are probably true, as I'm not really projecting, and yield return
saves a method call. (premature optimization anyone?)
public static IEnumerable<T> WithEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach(var x in source)
yield return x.With(action);
}
To be honest I probably wouldn't use WithEach
often, unless its an edge case where I'm passing an IEnumerable<T>
that may or may not be enumerated. I can imagine it being effective in generating complex hierarchies. However With
I use quite often, usually as a way to chain things together, i.e:
this.SomeObservable = someObservable
.With(o => o.Subscribe(this.OnNext)
.With(this._disposables.Add));