Неоднозначность с действием и параметром Func
Как возможно, что этот код
TaskManager.RunSynchronously<MyObject>(fileMananager.BackupItems, package);
вызывает ошибку компиляции
The call is ambiguous between the following methods or properties:
'TaskManager.RunSynchronously<MyObject>(System.Action<MyObject>, MyObject)' and
'TaskManager.RunSynchronously<MyObject>(System.Func<MyObject, bool>, MyObject)'
когда подпись действия
public void BackupItems(MyObject package)
и "неоднозначные" методы
static class TaskManager
{
public static void RunSynchronously<TInput>(Action<TInput> task, TInput param)
{
Task.Factory.StartNew(() => task(param));
}
public static bool RunSynchronously<TInput>(Func<TInput, bool> task, TInput param)
{
return Task.Factory.StartNew(() => task(param)).Result;
}
}
Мне кажется, что между этими методами существует большая разница. Что мне здесь не хватает?
EDIT:
Помимо принятого ответа, я просто встретил решение по аналогичному вопросу. Вот ссылка .
Ответы
Ответ 1
Причина в том, что возвращаемый тип метода не является частью его подписи. Таким образом, при разрешении правильной перегрузки компилятор только смотрит на параметр метода.
Самое простое решение - просто не использовать преобразование группы неявных методов. Все следующие компиляции:
TaskManager.RunSynchronously<MyObject>(
x => fileMananager.BackupItems(x), package);
TaskManager.RunSynchronously<MyObject>(
(Action<MyObject>)fileMananager.BackupItems, package);
TaskManager.RunSynchronously<MyObject>(
new Action<MyObject>(fileMananager.BackupItems), package);
Первый из них является самым изящным из них, но он также является единственным, у которого есть незначительное влияние производительности во время выполнения, из-за дополнительного перенаправления. Однако это воздействие настолько мало, что вам на самом деле все равно.
Ответ 2
Я столкнулся с той же проблемой, решение было:
var r = RunSynchronously<bool>(x =>
{
return true;
}, true);
RunSynchronously<bool>(x =>
{
}, true);
Теперь, почему компилятор не может этого сделать?
Ответ 3
Другое возможное объяснение этому в настоящее время заключается в следующем:
Код был написан для С# версии 7.3 (по умолчанию используется MSBuild 16.x, что соответствует VS2019), но попытка сборки осуществляется с более ранней версией С# (которая по умолчанию для MSBuild 15.x, что соответствует VS2017).
Более ранние версии С# выдают эту ошибку, но перегрузка корректно разрешается в С# 7.3.