2012-03-18 71 views
6

我试图写一个函数,函数作为它的一个参数 - 我以前做过很多次的任务。这工作得很好:功能可以运行一个方向,而不是其他

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); 

任何想法,为什么第一个作品,第二个不?

回答

5

第一个版本正在执行方法组转换作为“参数参数”匹配的一部分。这种转换不适用于扩展方法。对于拉姆达表达式也是如此 - 你不能写:

((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)的类型,然后在此规则中使用:

延伸方法C中它通过要求该方法调用是一个这些形式开始关闭我 .M Ĵ资格如果

  • expr到第一个参数M j的类型存在隐式身份,参考或装箱转换。

规范的注释版本则包括来自埃里克利珀此评论:

此规则确保使扩展double的方法不还扩展int。它还确保在匿名函数或方法组上没有定义扩展方法。

+0

也许你也应该解释为什么* *它不发生的扩展方法和lambda表达式。这是因为他们没有特定的委托类型。 'Func键'和'假设可能MyIntIntDelegate'具有相同的签名,但将是不同的类型,所以编译器可能不知道要转换成哪一个。 – Timwi 2012-03-18 00:18:53

+0

所以如果我得到这个权利,在第一个版本中有一个从'Method'到'Func'的隐式转换? – Joe 2012-03-18 00:19:56

+0

@Timwi:我正在那里... – 2012-03-18 00:24:11

0

Extension Methods“被称为好像他们是在扩展类型实例方法”。

在你的情况Double是不是一个实例,所以你不能调用扩展方法就可以了。

相关问题