委托实例与直接传递函数

Delegate instances vs passing function directly

我很好奇创建委托实例的意义何在。我知道它们是函数指针,但使用委托实例的目的是什么?

public delegate bool IsEven(int x);

class Program
{
    static void Main(string[] args)
    {
        int[] nums = new int[] { 1, 3, 4, 5, 6,7, 8, 9 };

        // creating an instance of delegate and making it point to 'CheckEven' function    
        IsEven isEven = new IsEven(CheckEven);

        // using delegate for parameter to get sum of evens
        int tot1 = Sums(nums, isEven);

        // passing in the function directly as parameter and not delegate instance
        int tot2 = Sums(nums, CheckEven);

        // using lambda expressions
        int tot3 = Sums(nums, x=> x%2==0);

        ReadKey();
    }

    public static int Sums(int[] nums, IsEven isEvenOdd)
    {
        int sum = 0;

        foreach(int x in nums)
        {
            if (isEvenOdd(x))
                sum += x;
        }

        return sum;
    }

    public static bool CheckEven(int x)
    {
        if (x % 2 == 0)
            return true;
        else 
            return false;
    }
}

起初认为如果您要传递的函数的功能没有复杂的实现,那么选择始终使用 lambda 似乎是最好的主意,否则我为什么不直接将我的函数传递到参数中?此外,使用 Lambdas 更容易更改它以计算赔率总和,而不是像我必须使用委托那样创建一个全新的方法。

即使您直接传递方法,您也已经使用了委托,如果委托定义未设置其期望值,Sums 方法将无法接收方法名称。

考虑将代表名称更改为 public delegate bool EvenOddStatus(int x);

您可以发送您的 CheckEven 方法或此方法:

public static bool CheckOdd(int x)
    {
        if (x % 2 != 0) // here changed
            return true;
        else return false;
    }

(这里当然可以使用lambda,但更复杂的场景就不行了)

现在,您的 Sums 方法可以根据调用代码(传递 CheckEvenCheckOdd)对奇数或偶数求和。

委托是指向方法的指针。您定义代码希望方法如何接收和return,调用代码稍后可以传递预定义的实现,方法或委托。

如果您的 Main 是另一种不知道求和、赔率或偶数的方法怎么办?它将有一个来自堆栈调用代码的委托。