février 2009 - Posts
In the previous post, I covered different aspects of the .NET Framework, namely, the situation at the time of the .NET 1.1 and the challenges it offered to both the programmers and the compiler. I also named a few needs the .NET Framework 2.0 had to meet in order to correct the grievances expressed when using .NET 1.1. The solution offered, as we saw, was the Generic namespace. We quickly check the benefits someone gets from using the Generics and I finally reviewed a few vocabulary so we could discuss the Generics on the same basis.
In this post, I will talk about the different Generics a programmer can use, the type constraints and type inference.
Generics
There are two kinds of Generics. There is the Generic type and the Generic Method.
4 Generic Types
The Generic type is composed of 4 elements: classes, interfaces, delegates and structures.
A Generic class is declared as followed:
Let's consider the following class:
When instantiating the class and calling the method ShowMyRealSelf, we get the following results:
Using a generic class:

Results:

How does it work when you try using interface? Consider the following interface and class implementations :
and the instantiation of the class is as follow:
will produce this result:

The last sample is quite simple (save for the French class names...). The class MyGenericClass implements a custom interface ITransformation. These two expect a type as an input and will produce another type as an output. This is shown by how the method Transform uses the type parameters. In this example, I transform some juice to wine. With the same class, I could transform milk to butter or yogurt or cheese (or with divine help, water to wine - no offence meant).
Generic Method
A generic class usually has generic methods. A generic method may return a generic type. it can also have generic type arguments. It must however define at least one type parameter. Here is the signature of the ConvertAll method from the generic class List.
List<TOutput> ConvertAll<TOutput>(Converter<TInput, TOutput> conv).
The ConvertAll method is quite useful for converting a list of one type to a list of another type. For example, someone could use this method to convert a list of candidates to a list of employees. Of course, this conversion implies somehow some logic to be applied to each item of the list to be converted. But first, let's have a look at the method ConvertAll.
Its return type is a List of TOutput. The TOuput type will be defined by the parameter type <TOutput>.
It expects to get as an argument a Converter type variable, which is a generic delegate with two type parameters. The first type parameter is the input type. The second, defined by the type parameter of the ConvertAll method, is the output type.
Using the previous example of candidates and employees, lets suggests we do have two classes: a Candidate class and an Employee Class. Thus, the generic delegate should be declared as follow:
The logic to convert a Candidate to an Employee should be a usual method like this one:
Finally, the overall class of hiring a bunch of candidates:

Type Constraints
Type constraints on generics are useful when someone wants to control how his generic will be used.
There are 4 type constraints:
- Reference type constraint: a generic method or a generic type with a reference constraints means the type parameter must be a reference type (an instance of Employee for example).
- Value type constraint: the parameter type can only accept value types (int, bool, enum, ect).
- Constructor constraint: the type parameter must have a parameterless constructor.
- Derivation constraint: it means the type parameter must be or derived from the specified class.
The way a constraint must be declared is as follow:
In the previous example, the generic method has a constructor constraint. It means an object of type T may be instantiated somewhere in the code. Since the type value may not be instantiated, a value type such like int, or bool is not allowed.
Constraints can be combined for a more secure use of the generic. As you might expect it, the type value can only be used alone.
Type inference
Type inference demonstrates the power of the compiler. It shows how much the compiler is "intelligent" enough to infer the type parameter based on the type argument.
Type parameter inference:

Usually, when using a generic method, specifying the type parameter is the standard. However, type inference allows the programmer to be a bit lazy and to omit the type parameter.
Both ways are good programming practice. However, specifying type parameter is, in my own opinion, a better practice for the sake of code readability.
Conclusion
With this second part of three blogs on Generics, we have looked at the two different kind of generics someone may encounter, generic type and generic method. In the section relative to generic method, we reviewed how to use the ConvertAll method from the generic List class. Also, we reviewed the 4 constraints which allows the programmer to limit the way his generics may be used. Finally we examined the type inference and how it could simplify code writing and how it takes its token on readability.
The last post will look at how the JIT manages memory with generics. Also, we will look at the 4 generic classes available.
Don't miss the last one!
Patrice
Mots clés Technorati :
.NET,
Framework 2.0,
Generics
The Generic namespace is a new feature of the .NET Framework 2.0 and it is, in my own opinion, the most important innovation the Framework 2.0 has to offer.
Overview of the situation from the .NET 1.1
Before the .NET Framework 2.0, programmers had to work with the ArrayList object in order to create arrays. The problem programmers experienced was the casting (or boxing) involved when using ArrayList. Adding instances of any object to an array involved, somewhere, a cast to an Object. When the time came to retrieve them, the programmer got an Object type and had to cast the Object to the right type. The last cast could lead to a runtime bug since the programmer had no way to know what type was in the ArrayList unless the code is properly documented. Also the compiler could not check the programmer's code. It had to trust the programmer for the right casting. Otherwise a bug could be generated at runtime.
Basic needs and requirements for the .NET 2.0
The needs and requirements the .NET Framework 2.0 had to meet were to cut down the number of casting (or unboxing) involved, allow a better validation at compile time, increase the Intellisense capabilities, decrease the number of bug at runtime due to bad castings and finally to enhance the readability of the code.
The .NET Framework answered these challenges with the Generic namespace.
Advantages of using Generics
When you start using the Generic, you get the following advantages compare to ArrayList. You get an implicit documentation of the code since the programmer knows the type of the objects in the array. The compiler knows what to expect and, therefore can perform validation at compile time. These checks increase the code robustness and decrease the possibilities of encountering a bug at runtime due to a bad casting. The reduction of the number of casting (and boxing) involved at runtime involve an augmentation of performances and a better memory management. When using Generics, the programmers reduce his code manipulation hence he increases his productivity.
Vocabulary
Before we get our hand dirty, let's check out a few terms commonly used with Generics.
Boxing means to take a Value Type (int, bool, enum) and wrap it into an instance of a reference type of an object (ie. from a integer to an object).
Unboxing means to unwrap the object and downcast it to a Value Type.
Casting means to convert a reference type to another reference type.
Implicit cast means there is a casting without using an conversion operator.
Explicit cast means a casting using a conversion operator.
Parameter type is what appears between angle brackets (<T>).
Argument type is the real type used with generics.
Unbound Generic type is a generic declaration without Argument Types.
Opened Constructed Type is a generic with argument types where the argument types are defined from somewhere else (like a generic class with generic methods).
Closed Constructed Type is a generic with argument types where the argument types are known.
Conclusion
This concludes the first part of the Generics where we saw why the Generics are so welcomed with the .NET Framework 2.0. We also had a look at a few vocabulary terms which are commonly used when you get started working with Generics.
The second part should look at the different generics someone may work with, the constraint types and type inference. This next part will also involve some code samples to get a better idea of the concept involved.
See you soon,
Patrice
Last Friday was my first presentation on a topic of my choice. The idea of such talks on lunch time to team members is from Laurent Duveau. These talks are good on developing skills for speaking in front of a crowd and to learn something on a topic relative to .NET.
The topic I chose is large. I decided to talk about Generics and Nullables. My experience with .NET Framework is somewhat short (definitely not as good as I would have liked). I already have worked with Generics for three years (since VS 2005 Beta) but never enough to talk about it with a new cutting edge so other team members could benefit from it. I used a pedagogic approach to prepare my presentation: an introduction to both subjects (What were the needs), a development body (classes, methods, advantages) and a conclusion (advantages and limitations).
The challenge for me for this first presentation was to talk about a topic on which I had a thin knowledge. In front of colleagues who are more knowledgeable on .NET Framework, the last thing I had in mind was to make a fool of myself or to talk only of general matter. That was for me a matter of self-esteem.
So I invested a lot of time on getting my presentation ready. "C# in Depth" and MSDN were my primary references. I also read a few blogs for complementary information. But the topic was deep. I should have let the Nullables for another talk. Next time I will talk about a technical topic, I will be more careful on selecting my subject. Thus, I could cut down my preparation time with less thing to cover, simpler demo to set up and fewer Powerpoint slides to get ready.
The presentation went well. The team members (Bruno, Vincent and Louis-Philippe) actively participated to the talk by asking questions, having conversations on the current topics or by asking an example or requesting a demo. I was proud of my preparation because the conversation leaded by Louis-Philippe went over a few things I was about to talk about.
This presentation gave me the opportunity to learn a few new things that I am now applying in my day to day developing tasks. Particularly, I use the Nullable type because the web application I am working on is laying on a database. Regarding the Generics, I learnt how to use the ConvertAll<T> method to convert a list of one type to a list of another type and I apply this method wherever I can. Also, I taught to a colleague how to use the Nullable and the ConverAll method and she is now using this new knowledge in her web application building.
All in all, the experience I got on presenting a technical topic was incredible: I build up a powerpoint slideshow, a demo to show a few code samples and the content preparation. I also got benefits from the presentation by having a deeper understanding of the .NET Framework and this understanding will be a good kick start for my next Microsoft Certifcation, the MCTS 70-536. There is no doubt in my mind that with this presentation my study on Generics and Nullable for the MCTS 70-536 certification is completed.
In this way, I must conclude that my first presentation was a complete success.
There are many ways to create a web site. However, there are two templates that are commonly used around the world. One is to use a single navigation tool such as a menu. Another one is to use two menus - a top menu beneath the web site banner and a left (or right depending on your tastes) menu.
The first time I used a sitemap, I struggled a few hours to get it right. The problem was me. I did not understand the workings on sitemap providers.
Using a custom sitemap filename
My first mistake, that day, was to use a custom sitemap file name, like MyWeb.sitemap instead of web.sitemap. When I added the SiteMapDataSource with default settings to my MasterPage, nothing worked properly.
Let's consider the following layout in a MasterPage:

As you can see on the screenshot, I added a sitemap file named MyWeb.sitemap. Here is the content
When I do a View in Browser of with the default configurations in the web.config file, I get an error from IIS:

This means the SiteMap provider is expecting a sitemap file named web.sitemap.
So, if you rename the MyWeb.sitemap file to web.sitemap and then view in browser, you are in your right to expect to see something different from the previous screen. Actually, the page is shown and IIS did not throw the previous error:
What is the trick? Or, more down to earth, how does it work?
Opening the web.config file will not get you any information. In fact, the web.config file has nothing relating to anything close to a sitemap reference. To find your answers, you need to open another web.config file located in the following directory:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
** WARNING: Unless you know what you are doing, if I were you I would not change anything in this file...
Excerpt of the web.config file:

The SiteMapDataSource first reads in the web.config file inside the solution to find its provider. Finding none, IIS redirects the SiteMapDatSource to the web.config file of the framework on which the web site is running.
While we have the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config file opened, we will copy the sitemap node into web.config file from the current web site project. The code must go inside the system.web node. A view in browser demonstrates the default web page is still showing correctly.
To be able to rename the web.sitemap file to something else, we need to change a few things in the new sitemap providers section from the current web.config.
First, you need to change the siteMapFile attribute. This is where you specify to IIS your sitemap file name. Let's change it for TopMenuWeb.sitemap. A quick glance in IE to see if the change has been taking into effect. It does. But what we get is another error:
This error means you have at least two site map providers having the same name.
After providing another name to the site map provider into our web.config file name, TopMenuWebSiteMapProvider for instance, we can see the results in IE. Everything works fine because we did not change the sitemap file yet. Doing so, IIS will throw a third error:

This error is caused by the SiteMapDataSource control in the masterpage. Earlier, we changed the sitemap provider in the web.config file. We also renamed the site map file. But all the while, the SiteMapDataSource control was always expecting the web.sitemap file. Since it can not find it anymore, IIS throws the above error.
The solution is to provide to the SiteMapDataSource control the site map provider name that will be bound to the TopMenuWeb.sitemap xml. In the SiteMapDataSource, you add the SiteMapProvider property and fill it with the sitemap provider name that is mapped to the existing sitemap file in the project, currently the TopMenuWebSiteMapProvider.
A refresh of IE shows the expected results.
Adding another sitemap
Adding as many sitemap files as desired is child play. The trick is to add as many sitemap providers in the web.config file.

And one more menu control bound to another siteMapDataSource control in the master page:

And finally, the leftMenuWeb.SiteMap file content:
Before going to the browser, I added some style to the MasterPage for the sake of seeing the skeleton of the web site. It is pretty ugly, please be kind and don't throw me any shoe...
Mainly, what is different from the previous browser results is that I changed an attribute in both SiteMapDataSource. I changed the ShowStartingNode value from true to false. This way, the menu shows not the root element but the first child level.
I hope this will quickly get you started when you start designing your new web site layout.
Best regards,
Patrice