首页 > 解决方案 > 堆栈中的 lambda 异常

问题描述

当我得到异常时,如果我有 lamda 函数,它很难读取错误堆栈。

例如对于此代码:

public void Test()
{
 Func<AnotherClass, bool> myLambda = (AnotherClass p) =>
    {
    if (p != null)
    {
     throw new Exception("Exception in method");
    }
     return true;
    };        
     AnotherClass ac = new AnotherClass();        
     var r = myLambda(ac);   
}
public class AnotherClass
{
}   

我会收到堆栈错误,例如:

"CSharpTests.exe Error: 0 : System.Exception: Exception in method
   at CSharpTests.MarketingEntityManager.<>c.<Test>b__0_0(AnotherClass p)
   at CSharpTests.MarketingEntityManager.Test()
   at CSharpTests.DisplayClassTest.Test()"

被问了很多次,什么是<>c.b__0_0

但另外有趣的是,可能是我在代码中使用myLabda名称的原因,它没有用于生成名称,而是生成了 b__0_0。

DisplayName 文本在哪里?

标签: c#.netlambda

解决方案


您的匿名方法命名myLambda。匿名方法的委托被分配给myLambda局部变量。实际上,您的匿名方法有一个“秘密”名称,由编译器赋予它,并且它是<Test>b__0_0(然后它被“隐藏”在名为 的嵌套类中<>c),但是这个名称可以根据同一类中的其他匿名方法。

举一个(退化的)例子(这在 Javascript 中很常见),这是合法的:

((Func<AnotherClass, bool>)((AnotherClass p) =>
{
    if (p != null)
    {
        throw new Exception("Exception in method");
    }
    return true;
}))(new AnotherClass());        

这里我们没有将方法的委托分配给任何变量,而是立即使用它来调用类。括号的数量是可怕的:-)

另一个经典例子:

var coll = new int[5];
var enu = coll.Select(x => x + 1).ToArray();

x => x + 1是一个匿名方法(其中一个委托是由 .NET 创建并传递给的Enumerable.Select)......任何地方都没有名称。


推荐阅读