Почему этот вызов неоднозначен для компилятора? - PullRequest
3 голосов
/ 20 июня 2020

Я экспериментирую с async / await и получаю ошибку компилятора для DoWorkAsync1.

Ошибка CS0121 Вызов неоднозначен для следующих методов или свойств: Task.Run<TResult>(Func<TResult>) и Task.Run<TResult>(Func<Task<TResult>>)

Для DoWorkAsync2 я добавил приведение типов, чтобы посоветовать компилятору, и это нормально. Почему у него проблемы с DoWorkAsync1? DoWorkAsync3 делает то же самое, только функция анонимна, и у нее тоже нет проблем.

static int Pom() { return 42; }

static async Task<int> DoWorkAsync1()
{
    var operation = Task.Run<int>(Pom);
    return await operation;
}

static async Task<int> DoWorkAsync2()
{
    var operation = Task.Run<int>( (Func<int>)Pom );
    return await operation;
}

static async Task<int> DoWorkAsync3()
{
    var operation = Task.Run<int>(() => 42);
    return await operation;
}

1 Ответ

3 голосов
/ 20 июня 2020

Причина, по которой вы получаете это, заключается в том, что возвращаемый тип не принимается (достаточно) во внимание при определении кандидатов на перегрузку в C# 7.2 или старше. Таким образом, список потенциальных кандидатов не содержит только 1 метод, и компилятор останавливается из-за ошибки неоднозначности.

Это было улучшено в C# 7.3 :

  • Для преобразования группы методов методы-кандидаты, тип возвращаемого значения которых не совпадает с типом возвращаемого значения делегата, удаляются из набора.

Это также объясняет, почему ваша лямбда работает, это не является преобразованием группы методов, другая часть компилятора срабатывает и, по-видимому, способна определить правильную перегрузку.

И действительно, если я скомпилирую ваш код с C# 7.0, 7.1 или 7.2, я get:

[CS0121] Вызов неоднозначен для следующих методов или свойств: 'Task.Run (Fun c)' и 'Task.Run (Веселье c ) '

... но если я изменю его на 7.3, он компилируется и использует перегрузку Func<int>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...