当传递一个方法时,编译器不能找出泛型类型
本文关键字:编译器 不能 泛型类型 方法 一个 | 更新日期: 2023-09-27 17:49:33
我在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)
{
}
}
谁能给我解释一下是什么问题?
不幸的是,类型推断的规则非常复杂。至少,我发现它们很复杂,我相信Eric和Mads正在为下一个规范版本简化它们——很可能不会改变实现的内容,但会改变规范中的表达方式。
在这种情况下,基本问题是方法组的参数类型对类型推断没有贡献,即使返回类型有贡献。特别是,从c# 4规范的7.5.2.6开始:否则,如果E是一个方法组,T是具有参数类型T1…Tk和返回类型Tb的委托类型或表达式树类型,并且E具有T1…Tk类型的重载解析产生具有返回类型U的单个方法,则从U到Tb进行下限推断。
处理返回类型,但不指定任何关于参数类型的内容。规范中我能找到的关于方法组参数类型的唯一相关部分是:
如果E是方法组或隐式类型匿名函数,T是委托类型或表达式树类型,则T的所有参数类型都是类型为T的E的输入类型
不幸的是,这并不能帮助修复任何边界。
基本上是这样的:
使用系统;public class Example
{
private interface ITest
{
int TestFunc();
int TestFunc2(string value);
}
public static void Main()
{
ITest t = null;
DoWork(t.TestFunc);
DoWork2(t.TestFunc2);
}
public static void DoWork<TResult>(Func<TResult> func)
{
}
public static void DoWork2<TResult>(Func<string, TResult> func)
{
}
}
…因为在这两种情况下,唯一需要推断的类型参数是返回类型。当您试图根据方法的输入参数推断类型参数时,事情就会出错:(
我假设编译器在这种情况下不会尝试推断类型,因为如果TestFunc重载,所期望的行为没有很好地定义。考虑:
private class Test
{
public int TestFunc(string str, int i) { return 0; }
public int TestFunc(string str, long i) { return 0; }
}
public static void Main()
{
Test t = new Test();
DoWork(t.TestFunc);
}
public static void DoWork<T1, T2, TResult>(Func<T1, T2, TResult> func)
{
}