C# 表达式/Func重载的编译器错误

C# 表达式/Func重载的编译器错误,c#,lambda,compiler-errors,expression,fakeiteasy,C#,Lambda,Compiler Errors,Expression,Fakeiteasy,截图上说的差不多。 我有在截图中看到的过载。当使用字符串作为第二个参数时,编译器应该知道第一个参数只能是Func,不能是表达式。 但是编译器抛出一个错误,称“带有语句体的lamda表达式无法转换为表达式树” 为什么编译器不能找出正确的重载 显式强制转换没有帮助。当我创建一个Func类型的局部变量,然后改用这个变量时,它就起作用了 使用的框架是Fakeitesy 1.24.0 编辑: 以下是显示行为的代码: public static void Main(string[] args) {

截图上说的差不多。 我有在截图中看到的过载。当使用字符串作为第二个参数时,编译器应该知道第一个参数只能是Func,不能是表达式。 但是编译器抛出一个错误,称“带有语句体的lamda表达式无法转换为表达式树”

为什么编译器不能找出正确的重载

显式强制转换没有帮助。当我创建一个Func类型的局部变量,然后改用这个变量时,它就起作用了

使用的框架是Fakeitesy 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();
    }
publicstaticvoidmain(字符串[]args)
{
//编译错误
A.CallTo(()=>Main(A.That.Matches)(字符串=>
{
返回true;
}("说明);;
//汇编
Func谓词=字符串=>
{
返回true;
};
A.CallTo(()=>Main(A.That.Matches(谓词,“description”));
Console.ReadLine();
}

问题不在对
匹配项的调用中。它位于对
CallTo
的调用中,它需要一个
表达式

显然,
表达式
不仅不能是具有语句体的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"));
}
静态void重载(操作a,字符串参数){}
静态空重载(表达式e){}
静态无效调用操作(操作a){}
静态void CallToExprAc(表达式a){}
静态void Main(字符串[]参数)
{
//工作
CallToAction(()=>重载(()=>{inti=5;},“hi”);
//不起作用-使用表达式重载
CallToAction(()=>重载(()=>{inti=5;}));
//不起作用-包装在外部表达式中
CallToExprAc(()=>重载(()=>{inti=5;},“hi”);
}
您的“将表达式bodied lambda放入本地”是否有效取决于fakeitesy的实现方式。我怀疑它在这里会起作用,但类似于LINQ to SQL的东西不会起作用——它只会在运行时失败,而不是在编译时失败

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

某些lambda表达式无法转换为表达式树类型:即使转换存在,也会在编译时失败。如果lambda表达式:

•具有块体

•包含简单或复合赋值运算符

•包含动态绑定的表达式

•是异步的


它没有说“包含无法转换为表达式树类型的lambda表达式”。

您可以发布代码而不是屏幕截图吗?您不能在仅表达式lambda主体中使用
return
string=>true
就足够了。@leppie:正确,但这不是重点。正如您在屏幕截图中所看到的,编译器应该使用Func重载,因此方法体应该可以。编译器给出了一个错误。问题是为什么。@leppie:第二个参数是字符串,因此表达式的重载应该是不存在的,因为这个重载只有一个参数。@leppie:很好,但没有默认值。啊。。说得好!是的,当您创建局部变量时,它在运行时也可以工作。谢谢@马尔很高兴听到这个消息,这是一个好地方——当然是一个有趣的问题。是的,但它现在也有意义了。非常感谢。因为我认为这是一个编译器错误,所以我提出了它。