Martin Doms
Martin Doms

Reputation: 8748

What does a stack trace including Namespace.ClassName.<MethodName>b__f mean?

I have an error log from a user with a stack trace that I don't fully understand. Here's how it looks

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

(I have removed the start of some namespaces to protect client's identity)

The part I don't understand is <GetCounts>b__f(...) and why it is called after Enumerable.Count[...](...). I assume it has something to do with the Count predicate but I can't quite decipher this.

If it helps the exception is an InvalidCastException. Here is some of the code involved (slightly modified to protect identity).

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
}

For what it's worth I'm pretty sure I know what's causing the error (ie where the bad cast is) but what I'm really curious about is that <GetCounts>b__f(...) member in the stack trace.

Upvotes: 3

Views: 749

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1502166

If you open up your assembly with Reflector, dotPeek etc, you'll see that the compiler has put the logic for your lambda expression inside GetCounts into another method - in this case <GetCounts>b__f. This is entirely normal for lambda expressions and anonymous methods - and some other C# features (iterator blocks, anonymous types, automatically implemented methods etc) also create members for you automatically.

The angle-brackets in the name are a good indication of it being compiler-generated: the compiler uses an unspeakable name - one which isn't a valid identifier - to make sure that not only will there not be any collisions with your other members, but you'll also never be able to refer to these "hidden" members within your code.

Upvotes: 4

Darren Kopp
Darren Kopp

Reputation: 77657

It means it is within something that the compiler generated, in this case being an anonymous delegate. More specifically, the compiler is generating a method named <GetCounts>b__f on your type.

Upvotes: 1

Related Questions