Подтвердить что ты не робот

Почему С# не может разрешить правильную перегрузку в этом случае?

Я столкнулся с странной ситуацией, которая не является двусмысленной, но средство перегрузки не так думает. Рассмотрим:

public static class Program
{
    delegate int IntDel();
    delegate string StringDel();

    delegate void ParamIntDel(int x);
    delegate void ParamStringDel(string x);

    static void Test(IntDel fun) { }
    static void Test(StringDel fun) { }
    static void ParamTest(ParamIntDel fun) { }
    static void ParamTest(ParamStringDel fun) { }

    static int X() { return 42; }
    static void PX(int x) { }

    public static void Main(string[] args)
    {
        ParamTest(PX); // OK
        Test(X); // Ambiguos call!
    }
}

Почему вызов перегрузки ParamTest разрешен правильно, но перегрузка Test неоднозначна?

4b9b3361

Ответ 1

Возможно, потому что https://msdn.microsoft.com/en-us/library/aa691131%28v=vs.71%29.aspx

Подпись метода специально не включает тип возврата и не включает модификатор params, который может быть указан для самого правого параметра.

И только разница между IntDel и StringDel находится в возвращаемом значении.

Более конкретно: https://msdn.microsoft.com/en-us/library/ms173171.aspx

В контексте перегрузки метода подпись метода не включает возвращаемое значение. Но в контексте делегатов подпись содержит возвращаемое значение. Другими словами, метод должен иметь тот же тип возврата, что и делегат.