为什么c#delegate调用接受函数名作为参数?

时间:2017-03-12 13:25:21

标签: c#

我试图了解代表。当我运行以下代码时:

public delegate void DelegateType1();

public static void callDelegate1(DelegateType1 callback) {
    callback();
}

void start() {
    callDelegate1(runMe);
}

void runMe() {
    Debug.Log("Why?");
}

它输出'为什么?'。

我的问题是:如果 CallDelegate1 采用 DelegateType1 类型的参数,为什么它还接受函数名作为参数?另外,这是一种不好的做法吗?我在网上看到的每个教程都将函数名称存储在 DelegateType1 类型的变量中。

1 个答案:

答案 0 :(得分:2)

复述:

void f(long l) { }
void g() { f(1); }
     

我的问题是:如果f采用long类型的参数,为什么它也接受int作为参数?

因为存在从intlong的隐式转换。

  

我的问题是:如果 CallDelegate1 采用 DelegateType1 类型的参数,为什么它还接受函数名作为参数?

因为存在从方法组到委托类型的隐式转换。

  

另外,这是一种不好的做法吗?我在网上看到的每个教程都将函数名称存储在 DelegateType1 类型的变量中。

最明确的形式是

void start() {
    DelegateType1 runMeDelegate = new DelegateType1(runMe);
    callDelegate1(runMeDelegate);
}

通过将其编写为转换,您可以使其不那么明确:

void start() {
    DelegateType1 runMeDelegate = (DelegateType1) runMe;
    callDelegate1(runMeDelegate);
}

通过隐式转换,您可以使其更加明确:

void start() {
    DelegateType1 runMeDelegate = runMe;
    callDelegate1(runMeDelegate);
}

最后,你可以完全摆脱变量:

void start() {
    callDelegate1(runMe);
}

他们都非常好,所有人都做同样的事情。第一种形式是代码生成器通常使用的形式,因为委托类型的显式构造是在不同语言中得到最广泛支持的东西。最后一种形式是程序员倾向于写的东西,当它对那些有足够C#经验的人来说是显而易见的。

教程并不专注于具有足够C#经验的程序员,因此为了更清楚地了解它们,他们可能会选择使用一种更详细的形式。如果它能帮助你理解,坚持使用该表格没有任何问题,但使用较短的表格同样没有错。