c# - 表达式/函数重载的编译器错误

标签 c# lambda compiler-errors expression fakeiteasy

屏幕截图说明了很多。 如屏幕截图所示,我有重载。当使用字符串作为第二个参数时,编译器应该弄清楚第一个参数只能是 Func 而不是表达式。 但是编译器会抛出一个错误,提示“带有语句主体的 lamda 表达式无法转换为表达式树”。

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

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

使用的框架是FakeItEasy 1.24.0

Wtf?

编辑:

这是显示行为的代码:

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"));
}

您的“将表达式主体 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 表达式”。

关于c# - 表达式/函数重载的编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27901928/

相关文章:

visual-studio - 构建 :Generic type 'Promise<T, R>' requires 2 type argument(s)

java - 无法在 ChronicleMap 中 close() map

java - int []无法转换为int return语句

c# - 如何在 C# 中的单个数组中添加不同类型的对象?

c# - 写入值数据分割

java - 如何使用 java 8 流和功能接口(interface)过滤掉这个列表?

python - 在 python 中初始化 lambda 函数列表

c# - 使用 LINQ 连接字符串

C# Simple 相当于 Enum 但具有多种数据类型?

C++11:函数指针表、Lambdas