Why is the call ambiguous? 'Task.Run(Action)&#

2020-08-09 08:17发布

问题:

Considering the following code:

public void CacheData()
{
    Task.Run((Action)CacheExternalData);
    Task.Run(() => CacheExternalData());

    Task.Run(CacheExternalDataTask);

    Task.Run(CacheExternalData);
}

public Task CacheExternalDataTask()
{
    // Long running code
    return Task.FromResult("Data");
}

public void CacheExternalData()
{
    // Long running code
}

Why is Task.Run(CacheExternalData) ambiguous? And Task.Run(CacheExternalDataTask) is not?

When calling Task.Run with CacheExternalData I would have thought it was clear to the compiler that the method does not return a Task and it should resolve to an Action?

回答1:

It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.

This is supposed to be fixed with new overload resolution in C# 7.3.



标签: c# task