2012-02-08 94 views
2

我有一个使用堆栈跟踪的用户的错误日志,我不完全理解。下面是它的外观什么是堆栈跟踪包括Namespace.ClassName。 <MethodName> b__f是什么意思?

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() 
    ..... 

(我已删除了部分命名空间的开始,以保​​护客户的身份)

的一部分,我不明白的是<GetCounts>b__f(...)以及为何Enumerable.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 
} 

对于什么是值得我敢肯定,我知道(在坏的演员阵容IE)是什么引起的错误。但我真的很好奇的是,<GetCounts>b__f(...)成员在堆栈跟踪。

+0

看起来像自动生成的代码。典型的来源是lambdas,'yield'-iterators和C#5的'async'-方法。在你的情况下,它显然是lambda。 – CodesInChaos 2012-02-08 20:37:45

回答

4

如果你打开你的组件,反射器,dotPeek等,你会看到,编译器已经把逻辑的lambda表达式中GetCounts成另一种方法 - 在这种情况下<GetCounts>b__f。这对于lambda表达式和匿名方法是完全正常的 - 还有一些其他C#特性(迭代器块,匿名类型,自动实现的方法等)也会自动为您创建成员。

名称中的尖括号是编译器生成的一个很好的指示:编译器使用一个难以形容的名字 - 一个不是有效的标识符 - 以确保不仅不会存在与您的其他成员发生任何冲突,但您也永远无法在代码中引用这些“隐藏”成员。

+0

谢谢Jon! (爱你的书,特别是你的F#与托马斯佩特里切克) – 2012-02-08 20:43:16

+0

@MartinDoms:我真的很尴尬,我真的不知道F# - 托马斯做了几乎所有的工作:) – 2012-02-08 20:54:53

+0

我精神上忽略了异步/等待关键字起初为什么我没有看到我的错误为ClassName.MethodName()。相反,我看到ClassName。 d__123.MoveNext()。我意识到如果你的代码使用async/await方法,编译器必须自动生成包装器代码来支持该功能。所以它是有道理的。 – Brock 2016-03-22 13:40:00

1

这意味着它是编译器生成的东西,在这种情况下是一个匿名代理。更具体地说,编译器正在为您的类型生成名为<GetCounts>b__f的方法。

+0

谢谢帮助了很多人。 – 2012-02-08 20:43:58