What I want to do is combine lambda syntax with "params" to carry out an action on a series of object.
Let's say I want to make a bunch of controls invisible.
After a bit of fiddling I ended up with an extension method:
public static void On<T>(this Action<T> actionToCarryOut,params T[] listOfThings)
{
foreach (var thing in listOfThings)
{
actionToCarryOut(thing);
}
}
and then I can create an action:
Action<Control> makeInvisible = c => c.Visible = false;
and then call it:
makeInvisible.On(control1,control2, control3,control4);
This isn't very nice syntax though - it feels horribly clumsy.
I can create a method "Apply" in my base class:
protected void Apply<T>(Action<T> action, params T[] appliedTo)
{
foreach (var item in appliedTo)
{
action(item);
}
}
and then call it like this:
Apply<Control>(
c => c.Visible = false,
control1,
control2,
control3,);
But that means repeating the method in every base class I need it in, and I lose the advantage of type inference.
Is there a less clumsy way of doing this?
Edit: The nicest method I've seen so far is the fluent approach, which (with a couple of tweaks) would allow me to write:
Apply.Method((Control c) => c.Visible = false).To(
control1,
control2,
control3,
control4};
This is 91 characters, compared to 107 for using a simple "foreach". Which leads me to believe that "foreach" might actually be the best approach after all!
You could use an extension method like this instead:
static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}
And then call it like:
new Control[] { control1, control2, control3 }.ForEach(makeInvisible);
Or simply
new Control[] { control1, control2, control3 }.ForEach(x => x.Visible = false);
If control1..n
are all of the same type you can omit the base class:
new[] { control1, control2, control3 }.ForEach(x => x.Visible = false);
Why not just call it as a regular static method instead of an extension?
public static class Apply
{
public static void To<T>(this Action<T> actionToCarryOut,params T[] listOfThings)
{
foreach (var thing in listOfThings)
{
actionToCarryOut(thing);
}
}
}
Then call it like this:
Apply.To<Control>(c => c.Visible = false,control1,control2, control3,control4);
EDIT
Here's a version that uses a Fluent syntax:
public class Apply<T>
{
private Action<T> _action;
public Apply(Action<T> action) { _action = action; }
public static Apply<T> Method(Action<T> actionToCarryOut)
{
return new Apply<T>(actionToCarryOut);
}
public void To(params T[] listOfThings)
{
foreach (var thing in listOfThings)
{
_action(thing);
}
}
}
Usage:
Apply<Control>.Method(c => c.Visible = false).To(control1,control2, control3,control4);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With