一个函数的作用是一个方向,而不是另一个方向

本文关键字:方向 一个 另一个 函数 作用 | 更新日期: 2023-09-27 18:28:19

我正试图编写一个将函数作为其参数之一的函数——这项任务我以前做过很多次。这很好:

int RunFunction(Func<int,int> f, int input) {
    return f(input);
}
int Double(int x) {
    return x*2;
}
// somewhere else in code
RunFunction(Double,5);

但这并不奏效:

public static class FunctionyStuff {
    public static int RunFunction(this Func<int,int> f, int input) {
        return f(input);
    }
}
// somewhere else in code
Double.RunFunction(5);

知道为什么第一个有效而第二个无效吗?

一个函数的作用是一个方向,而不是另一个方向

第一个版本正在执行方法组转换,作为"参数到参数"匹配的一部分。扩展方法不会发生这种转换。lambda表达式也是如此——你不能写:

((int x) = > x * 2).RunFunction(10);

或者。

C#4规范的第7.6.5.2节提供了扩展方法调用的详细信息。它首先要求方法调用具有以下形式之一:

expr.identifier ( )
expr.identifier ( args )
expr.identifier < typeargs > ( )
expr.identifier < typeargs > ( args )

表达式(expr)的类型然后用于此规则:

扩展方法Ci.Mj合格的如果

  • […]
  • 存在从expr到Mj的第一个参数类型的隐式身份、引用或装箱转换

规范的注释版本包括Eric Lippert的以下评论:

此规则确保生成扩展double的方法不会同时扩展int。它还确保没有在匿名函数或方法组上定义任何扩展方法。

扩展方法"就像它们是扩展类型上的实例方法一样被调用"。

在您的情况下,Double不是一个实例,所以您不能在它上调用扩展方法。