Contents

Source code and demo

Introduction

In the first part of How does it work in C#? article I discussed about the var, auto-implemented properties and += and -= of events in C#. In this article, I will be discussing about throwing an exception and how does it work and what is the internal mechanism for these, what is internal working mechanism of where and select clause of Enumerable class in C#.

How does it work?

In the following discussion we will see the internal working mechanism about the throw statement and where, select of Enumerable class.

throw an exceptionObject

Exception is one of the common scenarios for any application. As a result, proper exception management is one of the important tasks in application development. In here, I would like to discuss about throw statement in C#, how does throw anExceptionObject; or just throw works. I wrote a small program which will help me to explain the details. The task of this program is simple, it will raise an exception and throw it,

The above code will create a Person object and if any exception occurred during this creation it will catch that exception and from the catch block it throws the catched exception which is throw exceptionObject;. Now if we see the stack trace of those above code we will find out there is difference, stack trace for first version of the code is as below,

Fig: Stack trace of the first version of the code.

And stack trace of the second version of the code,

Fig: Stack trace of the second version of the code

From the above two images we can see the details of the stack trace is different.Now the question is how does it happens, to get the answer we will get help of ILDasm program, grab the exe of TestHarnessPart2 from the bin folder and drop into the ILDasm program , for the first version of the code we will see something like below,

Fig :IL code for using just throw in the catch block.

From the above image we can see exceptionObject has been defined as local variable using .locals init [1] but in the catch block compiler change the throw statement into

rethrow, which means compiler does not change the original stack trace of the exception object it is re- throwing the existing one, where as if we look into the following image for the second version of the above C# code,

Fig: IL code for using just throw excetpionObject in the catch block.

We can see exceptionObject has been defined as local variable as well, using the same way for the first version of the code for example, .locals init [1]. But in the catch block it is doing totally different stuffs compare to first version of the above code. In the catch block compiler load location of 1(ldloc.1) which is the exceptionObject

and throw that one. As a result, this exceptionObject will not hold all the stack traceraised earlier except the stack trace from this current state. Now the last bit of the puzzle is, what actually throw and rethrow statement does? From the Partition III CIL.doc retrieved from ECMA C# and Common Language Infrastructure Standards we can see what actually throw and rethrow does,

IL Instruction

Description

throw

Throw an exception. The throw instruction throws the exception object (type O) on the stack and empties the stack. So in relation to the second version of the code block it will be,

[1]class [mscorlib]System.Exception
exceptionObject

rethrow

Rethrow the current exception. The rethrow instruction is only permitted within the body of a catch handler. It throws the same exception that was caught by this handler. A rethrow does not change the stack trace in the object.

So it is clear that throw exceptionObject override the stack trace where as, just throw statement does not override the stack trace.

Where and Select of Enumerable

Before we start discussing about Where and Select, just have a quick look of the where and select clause’s signature,

Fig: Signature of the Where clause

Fig: Signature of the Select clause

Where and Select is two extension methods of Enumerable class in .Net. Following sections will discuss about the internal of Where and Select, how does it work. Before, we go ahead just bit of heads up about Func in .Net. According to MSDN, we can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate. A simple example of Func below,

So from the above code we can see TestFunc method accepting a Func as parameter and execute it just by doing return getLength(dataToCheck);, from the caller of this method is actually passing an anonymous method block for the Func parameter. Through out the entire discussion about where and select we will find this concept used many places,

Before we go ahead I like to show a bit of code created to explain the where and select statement,

The above code is not doing much rather check the booklist whether it has book which name length is greater than given length (lengthOfTheBookName). Now we will try to find out bit of internal working mechanism of Where and Select clause, where and select clause is defined in the Enumerable class and internal of the where clause is as below,

Fig: Where internal

From the above image we see Where method is calling another internal private class named WhereListIterator<T> which is doing all the work for us which is filter the booklist List based on the condition provided and return output.

From the above code we can see this.predicate(current)) line of code is actually executing the Func or anonymous method block in this case, <GetBookListWhichLengthIsGreaterThan>b__0 method. On the other hand, select clause is working like below,

Fig: Select internal

Also, from the above image we can see that there is one selector which is actually <GetBookListWhichLengthIsGreaterThan>b__1 method to select the item from the list. Now need to find out where is this <GetBookListWhichLengthIsGreaterThan>b__1 and

<GetBookListWhichLengthIsGreaterThan>b__0coming from? Please have a look image below, from the following image we can there is two method named <GetBookListWhichLengthIsGreaterThan>b__1 used for selector and <GetBookListWhichLengthIsGreaterThan>b__0 used for predicate of the where clause.

Fig: The output of WhereSelect test

Where and Select clause is using those two methods for doing the operation. Bit of more investigation to find out about it. Now we need the help of .Net Reflector and ILDasm. First grab the TestHarnessPart2.exe from the bin folder and drop into .Net Reflector, then we will find out following interesting stuff, a class <>c__DisplayClass3 with following details,

Which is actually containing the statement we defined for the select clause as below,

{
var currentBook = book;
return book;
}

Now to prove the above stuff, we will look at the IL code retrieved from ILDasm(also grab the TestHarnessPart2.exe from the bin folder and drop into ILDasm program) for the above C# code,

Fig: IL code of the GetBookListWhichLengthIsGreaterThan method

From the above image we can see where clause is using <GetBookListWhichLengthIsGreaterThan>b__0method of <>c__DisplayClass3 class and select clause is using <GetBookListWhichLengthIsGreaterThan>b__1 method. So it is clear now how does it work.

Limitation

There are no discussions about Query Expression and Lambda Expression.

It's nice to see how things work in the background, but what are the practical implications? Is there an important reason to know this, or is it just to satisfy intellectual curiosity? I'm missing a conclusion about why it's important to understand what's going on "under the covers" that would make me want to dig into the details...

The where and select clauses don't have a signature. Methods have a signature. where and select are not statements either.
Use of the right words is essential in communication, specially in programming languages. You use 'clause' instead of 'method' or 'method call', 'statement' instead of 'method' and instead of 'code block' or just 'code'.

"where and select clause" should be "Where and Select methods"
"the where and select statement" should be "the Where and Select methods"
"the statement we defined for the select clause as below" could be "the code we defined for the Select method as below"

A good start but the article is badly in need of editing. I realize that ESL may be an issue here so I am giving it a 4 instead of a lower score. I suggest breaking the article up into single topics. Easier to search, allows focus on a single topic, and a shorter article is easier to edit. Good use of figures however.

I think it's great to educate developers on the internals of C# - from a C++ background we generally had to know a bit more about memory etc but in C# so much is so straightforward it can be easy to not have any idea of how things are working.

With regards to the previous post - why not have two topics in one article? This is part of a larger series so there'll be lots of distinct sections so it makes sense to have a few topic in an article! I think this series is looking to be great, looking forward to more