Ответ 1
Правила вывода типа ужасно сложны, к сожалению. По крайней мере, я нахожу их сложными, и я считаю, что Эрик и Мэдс еще раз решили упростить их для следующей версии спецификации - возможно, не изменив того, что было реализовано, но изменили, как это выражено в спецификации.
В этом случае основная проблема заключается в том, что типы параметров групп методов не вносят вклад в вывод типа, даже если тип возврата делает. В частности, из 7.5.2.6 спецификации С# 4:
В противном случае, если E - группа методов, а T - тип делегата или тип дерева выражений с типом параметров T1... Tk и возвращаемым типом Tb, а разрешение перегрузки E с типами T1... Tk дает один метод с возвращаемым типом U, то вывод с нижней границей выполняется от U до Tb.
Это относится к типам возвращаемых данных, но не указывает ничего о типах параметров. Единственный соответствующий бит спецификации, которую я могу найти о типах параметров для групп методов, таков:
Если E - группа методов или неявно типизированная анонимная функция, а T - тип делегата или тип дерева выражений, то все типы параметров T являются входными типами E с типом T.
Это, к сожалению, не помогает зафиксировать какие-либо границы.
Итак, в основном это работает:
с помощью System;
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)
{
}
}
... потому что единственным типом параметра, который должен быть выведен в любом случае, является тип возвращаемого значения. Это когда вы пытаетесь вывести параметры типа на основе входных параметров метода, что все идет не так: (