C# 3.0 泛型类型推断 - 将委托作为函数参数传递 [英] C# 3.0 generic type inference - passing a delegate as a function parameter
问题描述
我想知道为什么 C# 3.0 编译器在将方法作为参数传递给泛型函数时无法推断方法的类型,因为它可以为同一方法隐式创建委托.
I am wondering why the C# 3.0 compiler is unable to infer the type of a method when it is passed as a parameter to a generic function when it can implicitly create a delegate for the same method.
这是一个例子:
class Test
{
static void foo(int x) { }
static void bar<T>(Action<T> f) { }
static void test()
{
Action<int> f = foo; // I can do this
bar(f); // and then do this
bar(foo); // but this does not work
}
}
我本以为我可以将 foo
传递给 bar
并让编译器推断 Action
的类型来自正在传递的函数的签名,但这不起作用.但是,我可以从 foo
创建一个 Action
而无需强制转换,那么编译器不能通过类型推断也做同样的事情是否有正当理由?
I would have thought that I would be able to pass foo
to bar
and have the compiler infer the type of Action<T>
from the signature of the function being passed but this does not work. However I can create an Action<int>
from foo
without casting so is there a legitimate reason that the compiler could not also do the same thing via type inference?
推荐答案
也许这会让事情更清楚:
Maybe this will make it clearer:
public class SomeClass
{
static void foo(int x) { }
static void foo(string s) { }
static void bar<T>(Action<T> f){}
static void barz(Action<int> f) { }
static void test()
{
Action<int> f = foo;
bar(f);
barz(foo);
bar(foo);
//these help the compiler to know which types to use
bar<int>(foo);
bar( (int i) => foo(i));
}
}
foo 不是一个动作 - foo 是一个方法组.
foo is not an action - foo is a method group.
- 在赋值语句中,由于指定了 int 类型,编译器可以清楚地分辨出您在谈论哪个 foo.
- 在 barz(foo) 语句中,由于指定了 int 类型,编译器可以判断您在谈论哪个 foo.
- 在 bar(foo) 语句中,它可以是任何带有单个参数的 foo - 所以编译器放弃了.
我添加了两种(更多)方法来帮助编译器确定类型(即 - 如何跳过推理步骤).
I've added two (more) ways to help the compiler figure out the type (ie - how to skip the inference steps).
从我阅读 JSkeet 的回答中的文章来看,不推断类型的决定似乎是基于相互推断的场景,例如
From my reading of the article in JSkeet's answer, the decision to not infer the type seems to be based on a mutual infering scenario, such as
static void foo<T>(T x) { }
static void bar<T>(Action<T> f) { }
static void test()
{
bar(foo); //wut's T?
}
由于一般问题无法解决,因此他们选择将存在解决方案的特定问题保留为未解决.
Since the general problem was unsolve-able, they choose to left specific problems where a solution exists as unsolved.
作为这个决定的结果,你不会为一个方法添加一个重载,也不会从所有使用单个成员方法组的调用者那里得到大量的类型混淆.我想这是一件好事.
As a consequence of this decision, you won't be adding a overload for a method and getting a whole lot of type confusion from all the callers that are used to a single member method group. I guess that's a good thing.
这篇关于C# 3.0 泛型类型推断 - 将委托作为函数参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!