Lambda Expressions
Lets imagine an scenario where we need a method signature to be implemented in different ways. For example a method signature to filter an array of chars, where the specific filtering implementation can vary depending on what needs to be filtered. In order to do this we will have a delegate that will indicate the work to be done:
The solution in the days of C# 1.0 was to create a named method that will perform our filtering operation. We will then pass this method as the delegate.
In order to avoid having to specifically create the method, the solution using the advantages of C# 2.0 was to use anonymous methods, but it turned out to be verbose and difficult to comprehend:
With C# 3.0 we have the option of using lambda expressions, which provides a nicer and more readable way of doing the same work. Lambda expressions take the following form:
(param1, param2, ...) => { expr }
So to code the same filtering example using this new C# feature, we will need to do the following:
Using lambda expressions will help us write less code and can help us make our code easier to understand, hence easier to maintain.
Anonymous Types
It is a common scenario to have to create business entity classes to move information from the data layer into the presentation layer. But this could get very tiresome and code extensive if we need to create a huge amount of business entity classes because each method in the business layer returns different information. This gets worse if each of the business layer methods is called only once by a specific presentation layer action, because that will force us to have several business entity classes with little use.
Anonymous types can help us deal with situations such as the one described above. They allow us to have methods returning unnamed business entities, without the need to specifically create the business entity class. Lets look at the following example:
This example shows us three things. First the use of the var keyword, which is new to C# 3.0 and, amongst other things, allows us to declare variables of anonymous or unknown types. Second the use of the new initializers in C# 3.0, that help us avoid having to specifically create constructors for each of the classes we want to use, and let us initialize the attributes right away when we initialize the variable. Third the use of anonymous types, where in the example we are creating a unnamed type with the attributes FirstName and LastName.
Visual Studio 2008 provides IntelliSense for all var datatypes, which helps the developer to know what does the variable contains once it has been initialized. Also there is compile time validation on the var datatypes, that prevents programmers from assigning a different datataype to a var variable that has already been initialized.
Extension methods
There may be cases when we would like to add additional functionality to a particular class, but we do not have access to the source code, or maybe it's just not feasible to modify it. Those particular scenarios are an example of where extension methods may help us in our development.
Lets have a look at the following code:
As you may notice, we are creating a method called Invert, and we are extending the .NET framework string class adding this method as an extension method. It is easy to recognize extension methods since they all start with the keyword this as part of the parameters.
Having extended the string class with the Invert method, we are allowed now to call this method from any string attribute in our code.
Partial methods
If there is a need to have methods that may or may not be called, depending on the specific need of the developer, partial methods are the right choice.
The idea behind partial methods is to allow the developer to choose wither he wants to execute a method or not. If he provides the method, then it gets executed, if he does not create the method then it will be just like if the method didn't exist. This helps a lot for cases when we may need to have pre and post methods for some particular action. Lets take a look at the following code:
Here we have created a Log partial class that writes a log entry whenever the DoLog() method is executed. This class contains a PreLog and a PostLog partial methods, which for the moment doesn't have any functionality. This code compiles fine, and if we call the DoLog() method, the string "Doing my logging." will be the only thing printed to the console. The story changes if we add the following code to the mix:In this other partial class we are adding functionality to the Pre and Post partial methods we defined in the first partial class. Now that we have some code for both methods it will be executed. This means that whenever the DoLog() method is called, the following will be printed to the console:
Doing pre-logging
Doing my logging
Doing post-logging
Query expressions
There are two ways in which we may query IEnumerable data using LINQ: using dot notation or using query expressions. Lets look at the following example:
This code shows the different ways in which we may query the array of strings. As you may see, the do notation treat queries as regular methods, while query expressions use a syntax very similar to sql queries (but inverted). In the end they both perform the same since query expressions get compiled into dot notation expressions.
Conclusion
We have taken a quick look into the most significant modifications that took place to C# in the .NET framework 3.5. It is important to keep in mind that most of these changes where required for the Microsoft team to put in place what they had in mind for LINQ, so some of them may look a little awkward or unnatural. Whatever the reason, this new additions have taken place, and we certainly have to study them to understand them, and to be able to identify the scenarios where this new features will provide great advantage to any code we may write for our applications.