【问题标题】:Delegate instances vs passing function directly委托实例与直接传递函数
【发布时间】:2018-05-10 04:06:09
【问题描述】:

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

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;
    }
}

起初认为,如果您要传递的函数的功能没有复杂的实现,那么选择始终使用 lambdas 似乎是最好的主意,否则我为什么不直接将我的函数传递给参数呢?此外,使用 Lambda 可以更轻松地更改它来计算赔率总和,而不是像使用委托那样创建全新的方法。

【问题讨论】:

  • “是什么阻止了直接使用该方法作为参数” - 您在上面发布的代码编译了吗?它应该有,而且这样做显然应该将这个问题回答为“没有”。它奏效了,所以没有什么能阻止你。坦率地说,根本不清楚你在问什么。
  • 充其量,您的问题主要是基于意见的,但这假设您已经知道无论您使用 new 运算符还是仅提供方法名称,都会发生同样的事情(一个新的委托实例是创建)。后者只是隐含地这样做,编译器会为您填写new IsEven(CheckEven)。如果你不明白这一点,那么你应该把精力集中在阅读可用的文档上,因为你在这里的问题会太宽泛(所以不是关于编程语言如何工作的手把手教程的地方)。
  • 我想我应该问一下使用委托实例有什么意义
  • 你知道什么是 lambda 函数吗?您似乎对委托和 lambda 感到困惑。
  • @Cosmik11 - 我认为令人困惑的是 lambda 只是一种创建委托的语法。

标签: c# linq lambda c#-7.0


【解决方案1】:

即使您直接传递了方法,您也已经使用了委托,如果委托定义未设置其期望,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)。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-27
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    相关资源
    最近更新 更多