是什么使方法的名称等同于动作委托?

时间:2011-11-12 02:30:39

标签: c# delegates

我只是在尝试并最终获得以下代码段:

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相同。

这是怎么回事?

3 个答案:

答案 0 :(得分:7)

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

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

  

可以将与委托签名匹配的任何方法(包括返回类型和参数)分配给委托。这使得可以以编程方式更改方法调用,并将新代码插入现有类中。只要您知道代理人的签名,就可以指定自己的委托方法。

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

在您的情况下,您的F1()F2()方法,不带任何参数并且不返回任何内容,与无参数Action delegate匹配的签名:

public delegate void Action();

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

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

答案 1 :(得分:3)

基本上,这是背景中发生的事情:

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

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

我希望这会有所帮助。

答案 2 :(得分:0)

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