为什么在没有返回值的lambda中添加throw会被推断为Func 而不是Action?

问题描述 投票:5回答:1

我遇到了一个问题,由于歧义的调用,我正在编写的库的某些测试代码无法编译,但用法对我来说似乎很清楚。经过进一步研究,我发现在没有返回值的lambda中添加throw似乎被推断为任何Func<T>中的T,而不是我期望的Action

以下人为的示例(可以粘贴到.NET Fiddle中)

using System;

public class Program
{
    class Foo
    {

        public void Method(Action action)
        {
            Console.WriteLine("Method A: " + action.GetType());
        }

        public void Method(Func<int> func)
        {
            Console.WriteLine("Method B: " + func.GetType());
        }

        /* // second call to Method becomes ambiguous if this is commented out.
        public void Method(Func<bool> func)
        {
            Console.WriteLine(func.GetType());
        }
        */

    }

    public static void Main()
    {
        var foo = new Foo();
        foo.Method(() => { });
        foo.Method(() => { throw new Exception("Foo!"); });
    }
}

结果在]中>

Method A: System.Action
Method B: System.Func`1[System.Int32]

也许假设Func<object>,因为抛出该错误无法推断任何返回类型...但是为什么不能呢?为何要推断并调用具体的Func<int>


另外,如果我尝试像这样创建一个隐式的Func<string>

foo.Method(() => 
{ 
    if (false) 
    { 
        throw new Exception("Foo!");
    }
    return "foo";
});

我遇到了之前从未遇到过的三个单独的编译错误:

Compilation error (line 38, col 16): Cannot implicitly convert type 'string' to 'int'
Compilation error (line 38, col 16): Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
Compilation error (line 38, col 9): Anonymous function converted to a void returning delegate cannot return a value

在上面人为的示例中研究这些仍然没有多大意义,因为这些错误本身是矛盾的。如果编译器可以确定它正在返回string并且不能转换为int,那么为什么对不同的返回类型或返回值的void委托感到沮丧?

任何人都可以阐明为什么编译器似乎难以理解我的意图吗?这是C#的限制,还是我看不到歧义?

我遇到了一个问题,由于歧义的调用,我正在编写的库的某些测试代码无法编译,但用法对我来说似乎很清楚。经过进一步调查,我发现添加...

c# lambda action type-inference func
1个回答
0
投票

有些情况您没有考虑。它们是:

© www.soinside.com 2019 - 2024. All rights reserved.