堆栈在lambda的例外

时间:2018-05-23 12:33:25

标签: c# .net 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()"

有人问了很多次, &lt;&gt; c.b__0_0

但另外有趣的可能是为什么我在我的代码中使用的 myLabda 名称,没有用于生成名称,并且生成了b__0_0。

和DisplayName文本在哪里?

2 个答案:

答案 0 :(得分:3)

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

要给出(退化)示例(在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)...在任何地方都没有名称。

答案 1 :(得分:0)

myLamda只是委托的名称​​引用您的方法。这不是方法的名称。后者是从编译器生成的,您无法更改它。

为了清楚这一点,想象一下你根本没有匿名方法,并且会在你的代表中引用命名的方法:

myLambda = MyMethod;

现在很明显堆栈跟踪包含MyMethod,而不是myLambda,不是吗?