How do you use Func<> and Action<> when designing applications?

后端 未结 9 834
情书的邮戳
情书的邮戳 2020-12-22 16:27

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

相关标签:
9条回答
  • 2020-12-22 17:30

    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);
    }
    
    0 讨论(0)
  • 2020-12-22 17:31

    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);
    }
    
    0 讨论(0)
  • 2020-12-22 17:33

    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#. :)

    0 讨论(0)
提交回复
热议问题