Expression/Func 重载的编译器错误

Compiler Error for Expression/Func overloads

屏幕截图说明了很多。 如屏幕截图所示,我有重载。当使用字符串作为第二个参数时,编译器应该弄清楚第一个参数只能是 Func 而不是表达式。 但是编译器会抛出一个错误 'A lamda expression with a statement body cannot be converted to an expression tree'。

为什么编译器无法计算出正确的重载?

显式转换没有帮助。有效的是当我创建一个 Func 类型的局部变量然后改用它时。

使用的框架是FakeItEasy 1.24.0

编辑:

这是显示行为的代码:

public static void Main(string[] args)
    {
        //compiler error
        A.CallTo(() => Main(A<string[]>.That.Matches(strings =>
                                                     {
                                                         return true;
                                                     }, "description")));

        //compiles
        Func<string[], bool> predicate = strings =>
                         {
                             return true;
                         };
        A.CallTo(() => Main(A<string[]>.That.Matches(predicate, "description")));

        Console.ReadLine();
    }

问题不在对 Matches 的调用中。它在对 CallTo 的调用中,它需要一个 Expression<Action>.

显然 Expression 不仅不能是带有语句体的 lambda 表达式,它也不能 包含 带有语句体的 lambda 表达式。

(我不确定您的“将 lambda 放入局部变量”解决方案是否 有效 或者它是否只是欺骗编译器并会在运行时失败。)

这是我整理的测试:

static void Overloaded(Action a, string param) { }
static void Overloaded(Expression<Action> e) { }

static void CallToAction(Action a) { }
static void CallToExprAc(Expression<Action> a) { }

static void Main(string[] args)
{
    // Works
    CallToAction(() => Overloaded(() => { int i = 5; }, "hi"));

    // Doesn't work - using the Expression overload
    CallToAction(() => Overloaded(() => { int i = 5; }));

    // Doesn't work - wrapped in an outer Expression
    CallToExprAc(() => Overloaded(() => { int i = 5; }, "hi"));
}

你的“将 expression-bodied lambda 放在本地”是否有效取决于 FakeItEasy 的实现方式。我怀疑它会在这里工作,但例如类似的东西LINQ-to-SQL 不会——它只会在运行时失败,而不是在编译时失败。

我不确定这是编译器错误、规范错误还是需要的行为。在 C# 规范的第 6.5 节中,我们有

Certain lambda expressions cannot be converted to expression tree types: Even though the conversion exists, it fails at compile-time. This is the case if the lambda expression:

• Has a block body

• Contains simple or compound assignment operators

• Contains a dynamically bound expression

• Is async

不会说“包含无法转换为表达式树类型的 lambda 表达式”。