传递方法时,编译器无法确定泛型类型

Mar*_*tin 11 c# generics c#-4.0

我在使用C#和泛型类型推断方面遇到了麻烦.我想编写一个方法来传递一个具有任何类型的方法,但编译器无法推断我传入的方法的类型.编译器总是抱怨消息

期待一种方法用'??? TestFunc(???,???)'签名

这是一个测试用例.

using System;

public class Example
{
    private interface ITest
    {
        int TestFunc(string str, int i);
    }

    private class Test : ITest
    {
        public int TestFunc(string str, int i) { return 0; }
    }

    public static void Main()
    {
        ITest t = new Test();
        DoWork(t.TestFunc);
    }

    public static void DoWork<T1, T2, TResult>(Func<T1, T2, TResult> func)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释我的问题是什么?

Jon*_*eet 3

不幸的是,类型推断的规则极其复杂。至少,我发现它们很复杂,并且我相信 Eric 和 Mads 正在尝试在规范的下一版本中简化它们 - 很可能不会改变实现的内容,而是改变规范中的表达方式。

\n\n

在这种情况下,根本问题是方法组的参数类型不会参与类型推断,即使返回类型会参与。特别是,从 C# 4 规范 7.5.2.6 开始:

\n\n
\n

否则,如果 E 是方法组,T 是参数类型为 T1\xe2\x80\xa6Tk 且返回类型 Tb 的委托类型或表达式树类型,并且类型为 T1\xe2\x80\xa6Tk 的 E 重载解析会生成返回类型为 U 的单一方法,则从 U 到 Tb 进行下限推断。

\n
\n\n

它处理返回类型,但没有指定有关参数类型的任何内容。我能找到的关于方法组参数类型的规范中唯一相关的部分是:

\n\n
\n

如果 E 是方法组或隐式类型匿名函数,并且 T 是委托类型或表达式树类型,则 T 的所有参数类型都是具有类型 T 的 E 的输入类型。

\n
\n\n

不幸的是,这无助于解决任何问题。

\n\n

基本上,这是有效的:

\n\n

使用系统;

\n\n
public class Example\n{\n    private interface ITest\n    {\n        int TestFunc();\n        int TestFunc2(string value);\n    }\n\n    public static void Main()\n    {\n        ITest t = null;\n        DoWork(t.TestFunc);\n        DoWork2(t.TestFunc2);\n    }\n\n    public static void DoWork<TResult>(Func<TResult> func)\n    {\n    }\n\n    public static void DoWork2<TResult>(Func<string, TResult> func)\n    {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

...因为在任何一种情况下都需要推断的唯一类型参数是返回类型。当您尝试根据方法的输入参数推断类型参数时,就会出现问题:(

\n