Lambda表达式隐藏了编译器错误;如何找到它们?

时间:2015-09-27 13:49:01

标签: c# visual-studio-2012 lambda nancy

使用VS-2012,我观察到如果有一个lambda表达式且它包含错误,编译器不会显示实际的语法错误。

举个例子:

public class CustomBoostrapper : DefaultNancyBootstrapper
{
    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
    {
        pipelines.BeforeRequest += ctx =>
        {
            if(1=1) //the actual error that needs to be corrected
            return new Response();
        };
    }
}

编译器将报告两个错误,通常是:

Operator '+=' cannot be applied to operands of type 'some type' and 'lambda expression'
Cannot convert lambda expression to type 'some type' because it is not a delegate type

但它甚至懒得报告if()中有一个非布尔表达式,并且在更正时,关于lambda表达式的错误消失了。更糟糕的是,它显然表现出任何类型的编译器错误。如果一个人正在编写一个复杂的函数并在某个地方蠢蠢欲动,那么他们只会留下两个非常一般的错误,并且必须寻找正文中的实际语法错误(或类似的东西)。有没有办法避免这种混淆?

注意:使用Nancy框架时会注意到此示例。我另外观察到它不仅仅是这个特定的功能,而且还有我使用lambda函数的任何地方。起初我认为它与编译器有关,但随后的注释表明,它可能与编译器或Visual Studio无关。

注意#2:我刚发现这只发生在匿名函数中。如果我定义函数然后从lambda表达式引用它,编译器会正确捕获函数中的错误。

1 个答案:

答案 0 :(得分:1)

我没有考虑这个完整的答案,但我发现如果我把它写成非匿名函数,那么编译器错误会按预期显示。所以,而不是:

pipelines.BeforeRequest += ctx =>
    {
        if(1=1) //the actual error that needs to be corrected
        return new Response();
    };

可以这样做:

protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
    pipelines.BeforeRequest += ctx => myFunc(ctx);
}

...

private Response myFunc(NancyContext ctx)
{
    if(1=1) //the actual error that needs to be corrected
    return new Response();
};

然后显示编译器错误" if(1 = 1)"正如所料。使用匿名错误时不是那么漂亮或简洁,但至少在调试更复杂的函数时它是一个临时的解决方法,而且在函数体内错误的地方并不是很明显。