什么使方法的名称等同于操作委托

本文关键字:等同于 操作 方法 什么 | 更新日期: 2023-09-27 18:14:23

我只是在做实验,最后得到了下面的代码片段:

public static class Flow {
    public static void Sequence(params Action[] steps) {
        foreach (var step in steps)
            step();
    }
}
void Main() {
    Flow.Sequence(() => F1(), () => F2());
    Flow.Sequence(F1, F2); // <-- what makes this equiv to the line above?
}
void F1() { }
void F2() { }

我没有意识到单独的方法名和Action是一样的。

为什么会这样?

什么使方法的名称等同于操作委托

在c#中,委托只不过是方法指针。它们可以指向类中的现有方法,或者完全独立的匿名委托对象。

上面链接的这一段应该解释你的代码中发生了什么:

任何与委托签名(由返回类型和参数组成)匹配的方法都可以分配给委托。这使得以编程方式更改方法调用成为可能,也可以将新代码插入到现有的类中。只要你知道委托的签名,你就可以分配你自己的委托方法。

也就是说,在解析委托类型时,考虑的是它们的签名,而不是它们的名称。

在你的例子中,你的F1()F2()方法,不接受参数也不返回任何东西,与无参数的Action委托具有匹配的签名:

public delegate void Action();

因此,它们可以隐式转换为Action

如果你试图传递一个具有不同返回类型或至少一个参数的方法,你将得到一个编译时错误,因为它不对应于Action的签名。

基本上,这就是在后台发生的事情:

void Main() 
{    
    Flow.Sequence(new Action(delegate(){ F1(); }), new Action(delegate(){ F2(); }));    
    Flow.Sequence(new Action(F1), new Action(F2)); 
}

它们不是完全相等的,但它们非常接近。它们将在运行时呈现相同的结果,唯一的区别是第一个序列调用中的参数将是一个调用匿名方法的Action,然后调用静态方法F1和F2;第二个Sequence调用将是一个Action,它调用静态方法F1和F2。

编译器使用从方法组到兼容类型委托的隐式转换(在这种情况下是一个不带参数的void返回方法),这里的方法名称是无关的。