简体   繁体   English

方法和扩展方法参数之间的类型推断差异

[英]Type inference discrepancy between method and extension method arguments

Let's say I have the following method defined: 假设我定义了以下方法:

int ReturnNumber(int number)
{
    return number;
}

Now, let's say that I also have the following two methods defined; 现在,我们还定义了以下两种方法: a regular method: 常规方法:

void Print(Func<int, int> function)

and an extension method: 和扩展方法:

static void Print(this Func<int, int> function)

I can call the former like this: 我可以这样称呼前者:

Print(ReturnNumber); // Regular method call, seems to implicitly convert ReturnNumber to Func<int, int>

but I can't do that with the latter: 但我不能使用后者:

ReturnNumber.Print(); // Extension method call, does not seem to do the implicit conversion -- results in compiler error

though I can do this: 虽然我可以这样做:

((Func<int, int>)ReturnNumber).Print(); // I perform the conversion explicitly

I'm assuming that there's some "magic" that happens when you pass a method as an argument to another method, and that the compiler is therefore able to guess that it should try to convert the ReturnNumber to Func<int, int> , whereas the compiler doesn't do any such thing for extension methods. 我假设当您将一个方法作为参数传递给另一个方法时,会发生一些“魔术”,因此编译器可以猜测它应该尝试将ReturnNumber转换为Func<int, int> ,而编译器不会对扩展方法执行任何此类操作。 Is this correct? 它是否正确? My question can be summarized as: why can't you call an extension method on a method, whereas you can call an extension method on a delegate instance? 我的问题可以概括为:为什么不能在方法上调用扩展方法,而可以在委托实例上调用扩展方法呢? Does it have something to do with the fact that the compiler doesn't treat methods as objects, but only treats delegates as objects? 它与编译器不将方法视为对象,而仅将委托视为对象有关吗?

That method group can be implicitly converted to Func<int, int> , which means if you're using that method group in a location where a Func<int, int> is expected (such as by passing it to a method who's parameter is Func<int, int> then it's able to convert it into such a delegate. 该方法组可以隐式转换Func<int, int> ,这意味着如果您在期望使用Func<int, int>的位置使用该方法组(例如,将其传递给参数为Func<int, int>则可以将其转换为这样的委托。

But until you've actually converted that method group into a Func<int, int> you can't call any instance methods on it, as it has none. 但是,除非您实际上已将该方法组转换为Func<int, int> ,否则您将无法在其上调用任何实例方法,因为它没有任何实例方法。 When you explicitly cast it to a Func<int, int> then you're changing that expression from a method group (which isn't itself a Func<int, int> ) into a Func<int, int> . 当您将其显式转换为Func<int, int>您正在将该表达式从方法组(本身不是Func<int, int> )更改为Func<int, int>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM