You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda函数抛出异常时栈追踪名称相关问题咨询

Lambda异常栈追踪与编译器生成方法的常见疑问解答

当你在Lambda函数中抛出异常时,栈追踪里的编译器生成名称确实会让人困惑,比如你给出的这段代码:

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.b__0_0(AnotherClass p) at CSharpTests.MarketingEntityManager.Test() at CSharpTests.DisplayClassTest.Test()"

下面针对你提出的三个问题逐一解答:

1. <><c.b__0_0>到底是什么?

这串名称是C#编译器自动生成的闭包类和对应方法的标识,拆解来看:

  • <>前缀是编译器用来标记「编译器生成的类型/成员」的特殊符号,目的是和你手动定义的代码区分开,避免命名冲突。
  • c是这个生成的嵌套类的名称(如果Lambda捕获了外部变量,类名通常会是<>c__DisplayClass0_0这类格式;如果没有捕获变量,会简化为<>c)。
  • b__0_0是类中对应Lambda逻辑的方法名,命名规则里的b代表"bound method",后面的数字是编译器用来区分同一类中不同Lambda的序号。

2. 为什么Lambda变量名myLambda没被用作生成方法名?

myLambda只是你在源代码中用来引用Lambda表达式的变量名,它和Lambda编译后实际生成的方法完全是两个概念:

  • 编译器处理Lambda时,只关注Lambda的逻辑本身,不会将变量名关联到生成的方法名上——毕竟变量名可以被修改、复用,甚至多个变量引用同一个Lambda,编译器需要一套稳定、无冲突的内部规则来生成这些隐藏成员。
  • 编译器生成的方法名是按照自身规范生成的,核心目的是保证唯一性,同时明确标识这是匿名函数生成的成员,所以不会采用用户定义的变量名。

3. DisplayName的位置在哪里?

这里的DisplayName如果指的是能关联到你定义的myLambda的友好名称,默认情况下不会出现在异常栈追踪里:

  • 编译器生成的方法本身并没有绑定你定义的变量名作为DisplayName,栈追踪里只会显示编译器生成的方法标识。
  • 如果你想在调试或反射中获取更友好的信息,只能通过额外手段:比如在代码中给Lambda添加注释、在调试器里查看变量引用关系,或者利用.NET Core/.NET 5+中的System.Diagnostics相关API,但这些都无法直接替换栈追踪里的编译器生成名称。

简单总结:这种命名方式是C#编译器处理匿名函数(包括Lambda)的标准行为,目的是在不污染用户命名空间的前提下,实现Lambda的逻辑执行。

内容的提问来源于stack exchange,提问作者justromagod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:48:05