sept. 24

In .NET 2.0, the notion of nullable types has been added. But I have the feeling that lots of developpers miss some basic understanding about this. So I have decided to add here some thoughts and explanation about the nullable types.

Recall on nullable types

Note that a primitive type has the following declaration in the .NET framework:
    public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int>
In comparison, the Nullable<T> class has the following declaration:
    public struct Nullable<T> where T: struct

int? i = null;                    //Equivalent to "Nullable<int> i = null;" 
Console.WriteLine(i);             //Display "" 
Console.WriteLine(i.HasValue);    //Display "False" 
Console.WriteLine(i.Value);       //Generates a "InvalidOperationException : 
                                  //Nullable object must have a value" 
Console.WriteLine(typeof(int?));  //Display "System.Nullable`1[System.Int32]" 
Console.WriteLine(i.GetType());   //Generates a "NullReferenceException" 
 
int? j = 10;
Console.WriteLine(j);             //Display "10" 
Console.WriteLine(j.HasValue);    //Display "True" 
Console.WriteLine(j.Value);       //Display "10" 
Console.WriteLine(typeof(int?));  //Display "System.Nullable`1[System.Int32]" 
Console.WriteLine(j.GetType());   //Display "System.Int32" 

Recall on the default value (default operator)

On generic types, you have the “default” operator.
This operator returns the default value for a generic parameter type, meaning:

  • “null” for reference types
  • “Zero whitewash” for the value types meaning for the composing types:
    • Zero for all the number types
    • “null” for the reference types
    • “Zero whitewash” for the value types (non primitive).
public class GenericClass<T>
{
   public override string ToString()
   {
      object o = default(T);
      return o == null ? "null" : o.ToString();
   }
 
   public static void Main()
   {
      GenericClass<int> myInt = new GenericClass<int>();
      GenericClass<object> myObject = new GenericClass<object>();
      Console.WriteLine(myInt.ToString());    //Display “0” 
      Console.WriteLine(myObject.ToString()); //Display “null” 
   }
} 

The nullable types are in fact the structure “Nullable<T>”that expose a method “GetValueOrDefault”. This method will act as the “default” operator in case the nullable types do not have any value.

Basic arithmetic operations on nullable types

int? i = null;
int? j = 10;
 
//To be able to add the value of a nullable type, we can use the “Value” property 
//after testing that this type has a value. 
int total1 = 0;
if ( i.HasValue )
   total1 += i.Value;
if ( j.HasValue )
   total1 += j.Value;
Console.WriteLine(total1);
 
//Or we can use the “GetValueOrDefault” method on the object 
int total2 = i.GetValueOrDefault() + j.GetValueOrDefault();
Console.WriteLine(total2); 

It will of course depend of the cases, but usually the second syntax will allow having clearer (and shorter) code.

Comparison operators with nullable types

int? i = null;
int? j = 10;
int? k = 20;
 
Console.WriteLine(i < j);     //Display "False" 
Console.WriteLine(i > j);     //Display "False" 
Console.WriteLine(i == j);    //Display "False" 
Console.WriteLine(i != j);    //Display "True" 
 
Console.WriteLine(k < j);     //Display "False" 
Console.WriteLine(k > j);     //Display "True" 
Console.WriteLine(k == j);    //Display "False" 
Console.WriteLine(k != j);    //Display "True" 

So you can use the comparison operators without any problem. You don’t need to test the “HasValue” property before doing the comparison. Just keep in mind that this very short syntax is converted by the compiler as follows :

//The following syntax 
i < j 
//is transformed (at compile-time) into 
(i.GetValueOrDefault() < j.GetValueOrDefault()) && (i.HasValue & j.HasValue)

Just note that if you need to do a special treatment in the “null” case, you will have to use the “HasValue” property.

if ( i < j ) 
{ 
   // Only in the case i AND j have a value AND i.Value < j.Value 
} 
else 
{ 
   // Will be called whenever i OR j do not have a value OR i.Value >= j.Value 
} 
Tags:
sept. 18

My team and I are working for two years on a big XP project now. Among the 8 developpers, we can find all the levels and all the educations. Some are engineers - for which IT is their first choice - and some were doing another job and have decided to switch direction.
Of course this does not mean that a kind of developper is better than another one, but this mean that we all have a different approach to a same problem, a different point of view, interpretation and understanding, depending of our experience, meaning habits, past and education.

Most of us had not done XP before this project, meaning that we had learned the methodology progressively and we have started to own it and to "customize" it to our needs.

For some of the group, XP has oftenly been considered as an excuse to do less. I mean I encounter people saying "No we shouldn't do that, because XP is iterative and so we should do only what we need for now. Let's do it simple, not more".
Said like that, it seems to be fully correct. Nevertheless, there is a huge misunderstanding behind this word of "simple".

Are we speaking of "simple code" or of "simpler solution" ?
There seem not to be any difference but it's huge and will drive all the future development. We could turn this question in another one - as it is in my view to exact ending of it - shall we throw the code in the future or shall we make it evolve ?

I have regulrarly fought during these 3 years to say : "simple do not mean to write very basic (too basic) code. So simple that this code will be thrown away in the next iteration because it is too simple (understand too low level, too concrete, without any level abstraction raised) to evolve".

I'm now reading the book "Extreme.NET" by Neil Roodyn. Not a very recent one so the .NET part is a bit outdated but the "philosophical part" is still very accurated.
There is a very nice sentence in it that, in my view, summarize all this to give a simple answer ;-)
And by "simple" here, I mean an answer that should be able to make all developpers think about themselves and what they produce.

"Simple does not mean easy. Developpers who are starting out often misinterpret this as "Do the easiest thing you can possibly do." [Pierre-Emmanuel Dautreppe's note : I would even say : "Do the more stupid thing you can"] This is incorrect; simple is often a lot harder to achieve than complicated. [...] The switch statement is easier to write, but the polymorphism provides a simpler solution."

A "simple solution" means a clear and open solution, a solution that will be simple to make evolve, that won't be reluctant to changes.

At the same time, Roy Osherove speaks about unit testing and call them TATs or TTLs, meaning "Throw-Away Tests" and "Tests That Lasts". For sure, it's a point that should make all of us think about our work.
For sure, I will come back often to this point in the future.

Tags:
sept. 14

Didier Pieroux has sent me this interesting news ! I will simply translate the information he gave me:

"Here is a news that has probably been unnoticed in the .NET world but for sure not in the world criticism systems: http://www.adacore.com/2007/09/10/adacore-first-to-bring-true-net-integration-to-ada/

The interest of this news is not the fact that we can develop in ADA on the .NET stack but that this is now followed and developped by a major actor on the ADA world (contrary to A# that has been developped by a university of the USAF [Note : United States Air Force]). Of course, ADA will not takie some market positions to C# or VB. Of course, ADA won't become more popular because it is available on .NET.

No the main important thing is - in my opinion - that it seem to have a demand of the domain that are traditionnaly ADA-oriented (and so Unix-oriented) to open to the .NET world (and so Microsoft). Until now, I had only seen from these domains a true interest to Java. A good news for the "Microsoftees" world in general Wink.

Interesting also, thare has been a previous initiative to compile ADA to JVM. Today, this initiative is in a clinical death state. I imagine that if AdaCore do a similar step to .NET, this means they think it will be more successfull than with Java !"

 

Interesting step indeed ! And do not forget that in the same time Microsoft also do a step in the opposite direction with Silverlight and Linux. Loïc Bar has regrouped many articles speaking of that in this news.

 

sept. 11

Crystal Reports may generate some temporary files ('*.tmp', '*.rpt') in a temp folder (typically the c:\windows\temp folder or you temp folder in "Local Settings"). This is not a big deal because these files are quite small (between 0k and 200k for the ones I have seen during my investigations) but it can be a potential problems as they are very numerous (till 10 for a single export) and contains some potentially sensitive information (some data of your exports).

I have seen that these files are generated by the following methods:

  • SetDataSource
  • ExportToStream

How to correct this problem ?

  • Be sure to call the "Close()" method on your report object. This will automatically delete all the temporary generated files. In fact almost all of them as you will still have a "temp_xxx.rpt" file generated, even if you call the ExportToStream method.
  • Be sure to call the "Dispose()" method so Crystal Reports will release all the locks it may have on the object and the last generated file will be deleted

Of course, you could call only the "Dispose()" method as it will call internally the "Close()" method, or even not calling any of them but using the "using" syntax

sept. 09
CITCON Brussels 2007

CITCON (Continuous Integration & Testing Conference) comes to Brussels in October 19th & 20th (friday evening and saturday).

Interested in 1-day of great conference about CI and testing ? Join me there !

Be careful, it's limited to the first 100 subscribee so hurry up.

Need more information about CITCON ? Visit their website dedicated to Brussels !