X =>将&QUOT Lamdba; {抛出..}"推断的匹配函数功能< T,任务>在重载的方法? [英] Lamdba of "x => { throw .. }" inferred to match Func<T,Task> in overloaded method?

查看:102
本文介绍了X =>将&QUOT Lamdba; {抛出..}"推断的匹配函数功能< T,任务>在重载的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白,为什么C#结束了在以下LINQPad code执行一个不正确的扩展方法:

I don't understand why C# ends up executing an incorrect extension method in the following LINQPad code:

void Main()
{
    // Actual: Sync Action
    "Expected: Sync Action".Run(x => { x.Dump(); });

    // Actual: Async Task
    "Expected: Async Task".Run(async x => { await System.Threading.Tasks.Task.Run(() => x.Dump()); });

    // Actual: Async Task!!
    "Expected: Sync Action".Run(x => { throw new Exception("Meh"); });
}

static class Extensions
{
    public static void Run<T>(this T instance, Action<T> action)
    {
        "Actual: Sync Action".Dump();
        action(instance);
    }

    public static void Run<T>(this T instance, Func<T, System.Threading.Tasks.Task> func)
    {
        "Actual: Async Task".Dump();
        func(instance).Wait();
    }
}

有人可以帮助我了解为什么编译器认为拉姆达返回任务吗?

Can someone help me understand why does the compiler think that the lambda returns a Task here?

我期望看到的实际:同步行动,在第三调用运行()因为没有在拉姆达表示这是一个Func键返回任务

I expected to see "Actual: Sync Action" in the third call to Run() since nothing in the lambda indicates that this is a Func returning Task.

推荐答案

这是一个简单的重载问题。显然,在lambda X =&GT; {抛出新的异常(咩); } 可以转换到任何一个动作&LT; T&GT; 或一个 Func键&LT; T,SomeNonVoidType&GT; (以及许多其它代表类型无关这个问题)。它只是说美元的这种字母p $ PFER后者C#的重载决策规则。

This is simply an overload resolution issue. Clearly, the lambda x => { throw new Exception("Meh"); } can be converted to either an Action<T> or to a Func<T, SomeNonVoidType> (as well as to many other delegate types irrelevant to this question). It's simply C#'s overload resolution rules that prefer the latter in this case.

下面是一个更重presentative例如:

Here's a more representative example:

void Main()
{
    // Output: Func<T, int>
    "Test".WhatsThis(x => { throw new Exception("Meh"); });
}

static class Extensions
{
    public static void WhatsThis<T>(this T dummy, Action<T> action)
    {
       "Action<T>".Dump();
    }
    public static void WhatsThis<T>(this T dummy, Func<T, int> func)
    {
       "Func<T, int>".Dump();
    }
}

至于为什么的是这样的话,我不是100%肯定,但随便看的规范显示我的下面可能的解释(重点煤矿):

As for why this is the case, I'm not 100% sure, but a casual look at the spec shows me the below likely explanation (emphasis mine):

7.5.3重载

[...]

7.5.3.3从EX pression更好的转换

7.5.3.3 Better conversion from expression

由于一个隐式转换C1,它把来自一名前pression E至一个类型T1和隐式转换C2,它把来自一名前pression E至一个类型T2,C1是一个比C2更好的转换如果发生以下中的至少一个成立:

Given an implicit conversion C1 that converts from an expression E to a type T1, and an implicit conversion C2 that converts from an expression E to a type T2, C1 is a better conversion than C2 if at least one of the following holds:

[...]

•E为匿名函数,T1或者是委托类型D1或前pression树型   防爆pression&LT; D​​1&GT; ,T2要么是委托类型D2或前pression树   键入防爆pression&LT; D​​2&GT; 键,下列情况之一成立:

• E is an anonymous function, T1 is either a delegate type D1 or an expression tree type Expression<D1>, T2 is either a delegate type D2 or an expression tree type Expression<D2> and one of the following holds:

[...]

•D1具有返回类型Y和D2是无效的返回

这篇关于X =&gt;将&QUOT Lamdba; {抛出..}&QUOT;推断的匹配函数功能&LT; T,任务&GT;在重载的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆