В C #, когда вы используете имя метода без круглых скобок, оно называется группой методов и не имеет представления, кроме как во время компиляции. Группа методов может представлять более одного метода (из-за перегрузок и переопределений), поэтому для неявного определения, какой метод необходим, должен быть указан целевой тип делегата.
В вашем случае вам интересно, почему тип параметра метода расширения не будет вызывать разрешение функции. Проще говоря, расширение оценивается после того, как тип известен, то есть этот параметр нельзя использовать в качестве цели неявного преобразования.
Пример того, почему он сломается:
class Test
{
void M (void) // Fits Action delegate
{
}
int M (int) // Fits Func<int,int> delegate
{
return 5;
}
void Test()
{
M.Exec(); // UHOH!!! Which Exec to resolve to ???
}
}
public static class Extensions
{
public static void Exec(this Action action) { }
public static void Exec(this Func<int, int> func) { }
}
Как видите, конфликт существует, но на самом деле конфликт никогда не происходит, потому что C # даже не пытается найти соответствующее расширение с группой методов.
Обратите внимание, как это не будет работать:
class A
{
public static implicit operator int (A a)
{
return 5;
}
void F()
{
A a = new A();
a.Blah(); // Error! It won't implicitly try C.Blah()
}
}
public static class C
{
public static void Blah (int i)
{
}
}
C # не будет совпадать с A
до C.Blah(int)
, поскольку для этого потребуется неявное преобразование.