什么使方法的名称等同于操作委托
本文关键字:等同于 操作 方法 什么 | 更新日期: 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返回方法),这里的方法名称是无关的。