【问题标题】:What does a stack trace including Namespace.ClassName.<MethodName>b__f mean?包含 Namespace.ClassName.<MethodName>b__f 的堆栈跟踪是什么意思?
【发布时间】:2012-02-09 04:27:08
【问题描述】:

我有一个来自用户的错误日志,其中包含我不完全理解的堆栈跟踪。这是它的外观

Stack Trace:
   at ...Presenters.Forms.PresenterHome.<GetCounts>b__f(IActivityItem activityItem)
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source, Func`2 predicate)
   at ...Presenters.Forms.PresenterHome.GetCounts(Int32& completeCount, Int32& incompleteCount)
   at ...Presenters.Forms.PresenterHome.UpdateSummaryPanel()
   .....

(我已经删除了一些命名空间的开头以保护客户的身份)

我不明白的部分是&lt;GetCounts&gt;b__f(...) 以及为什么在Enumerable.Count[...](...) 之后调用它。我认为它与Count 谓词有关,但我无法完全理解这一点。

如果有帮助,例外是InvalidCastException。以下是一些涉及的代码(稍作修改以保护身份)。

void UpdateSummaryPanel()
{
    int completeCount;
    int incompleteCount;
    GetCounts(out completeCount, out incompleteCount);
    ...
}

private void GetCounts(
    out int completeCount, 
    out int incompleteCount)
{
    incompleteCount = _applicationContext.ActivityItems.Count(
        activityItem => activityItem.ActivityType == ActivityTypes.Foo
                        && ((FooActivity) activityItem).Status != CaptureStatus.Bar);

    // similar code for other count
}

对于它的价值,我很确定我知道导致错误的原因(即错误的演员表在哪里),但我真正好奇的是堆栈跟踪中的 &lt;GetCounts&gt;b__f(...) 成员。

【问题讨论】:

  • 看起来像自动生成的代码。典型的来源是 lambdas、yield-iterators 和 C#5 的 async-methods。在你的情况下,它显然是 lambda。

标签: c# stack-trace


【解决方案1】:

如果您使用 Reflector、dotPeek 等打开程序集,您会看到编译器已将 GetCounts 中的 lambda 表达式的逻辑放入另一个方法中 - 在本例中为 &lt;GetCounts&gt;b__f。这对于 lambda 表达式和匿名方法是完全正常的 - 并且一些其他 C# 功能(迭代器块、匿名类型、自动实现的方法等)也会自动为您创建成员。

名称中的尖括号很好地表明它是由编译器生成的:编译器使用一个不可描述的名称——它不是一个有效的标识符——以确保不仅不会与您的其他成员发生任何冲突,但您也永远无法在代码中引用这些“隐藏”成员。

【讨论】:

  • 谢谢乔恩! (喜欢你的书,尤其是你和 Tomas Petricek 合作的 F#)
  • @MartinDoms:很尴尬,我真的不懂 F# - Tomas 做了几乎所有的工作 :)
  • 我在心里跳过了 async / await 关键字,所以起初它并没有为我点击,为什么我没有看到我的错误是 ClassName.MethodName()。相反,我看到的是 ClassName.d__123.MoveNext()。我意识到如果您的代码使用 async / await 方法,编译器必须自动生成包装器代码以支持该功能。所以这是有道理的。
【解决方案2】:

这意味着它在编译器生成的东西之内,在这种情况下是一个匿名委托。更具体地说,编译器正在为您的类型生成一个名为 &lt;GetCounts&gt;b__f 的方法。

【讨论】:

    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 2020-06-26
    • 2011-09-13
    • 2019-06-30
    • 2011-11-09
    相关资源
    最近更新 更多