All the examples I can find about Func<> and Action<> are simple as in the one below where you see how they technically work but I would like
I use the Action
and Func
delegates all the time. I typically declare them with lambda syntax to save space and use them primarily to reduce the size of large methods. As I review my method, sometimes code segments that are similar will stand out. In those cases, I wrap up the similar code segments into Action
or Func
. Using the delegate reduces redundant code, give a nice signature to the code segment and can easily be promoted to a method if need be.
I used to write Delphi code and you could declare a function within a function. Action and Func accomplish this same behavior for me in c#.
Here's a sample of repositioning controls with a delegate:
private void Form1_Load(object sender, EventArgs e)
{
//adjust control positions without delegate
int left = 24;
label1.Left = left;
left += label1.Width + 24;
button1.Left = left;
left += button1.Width + 24;
checkBox1.Left = left;
left += checkBox1.Width + 24;
//adjust control positions with delegate. better
left = 24;
Action<Control> moveLeft = c =>
{
c.Left = left;
left += c.Width + 24;
};
moveLeft(label1);
moveLeft(button1);
moveLeft(checkBox1);
}
They're also handy for refactoring switch statements.
Take the following (albeit simple) example:
public void Move(int distance, Direction direction)
{
switch (direction)
{
case Direction.Up :
Position.Y += distance;
break;
case Direction.Down:
Position.Y -= distance;
break;
case Direction.Left:
Position.X -= distance;
break;
case Direction.Right:
Position.X += distance;
break;
}
}
With an Action delegate, you can refactor it as follows:
static Something()
{
_directionMap = new Dictionary<Direction, Action<Position, int>>
{
{ Direction.Up, (position, distance) => position.Y += distance },
{ Direction.Down, (position, distance) => position.Y -= distance },
{ Direction.Left, (position, distance) => position.X -= distance },
{ Direction.Right, (position, distance) => position.X += distance },
};
}
public void Move(int distance, Direction direction)
{
_directionMap[direction](this.Position, distance);
}
Using linq.
List<int> list = { 1, 2, 3, 4 };
var even = list.Where(i => i % 2);
The parameter for Where
is an Func<int, bool>
.
Lambda expressions are one of my favorite parts of C#. :)