我只是在尝试并最终获得以下代码段:
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相同。
这是怎么回事?
答案 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返回方法不带参数),此处的方法名称是无关紧要的。