By now, you have likely read Somasegar's blog entry on nullable types in VS 2005.
You know that nullable types are now recognized by the CLR and no longer implement INullableValue. What you may not have realized is that nullable types no longer implement IComparable. The problem this introduces is that there appears to be no way to refer to value, nullable, and reference types generically for comparison. In particular, I'm working on an object model which includes dirty state tracking and similar functionality. In the base class, I have the following generic method:
protected void SetProperty<T>(ref T currentPropertyValue, T newValue) where T : IComparable
Inside, the code does a .CompareTo, checks the result, and then if different, sets the currentPropertyValue to the newValue, raises an event and sets the dirty and valid flags. You cannot pass a nullable type into that method as nullable types do not implement IComparable. It will take regular ints, strings, classes that implement IComparable, etc., but will not take nullable types.
You could simply remove the constraint, and do a != check for equality, but that produces a compiler error.
protected void SetProperty<T>(ref T currentPropertyValue, T newValue)
You get a compile error even if you impose a constraint of value type on the generic:
protected void SetProperty<T>(ref T currentPropertyValue, T newValue) where T : struct
Another option would be to ignore the IComparable interface, and simply do a .Equals inside the code. That also does not work in all cases, as you would need to make sure .Equals is overridden in the inherited classes. While you can impose that on your developers by policy, .Equals comes by default and does reference equality checking whereas IComparable requires a developer to explicitly implement the interface and add in the correct code for value equality checking. The former is easy to do, but is also very easy to forget and hard to debug if missed. The latter is preferred as it really says to the world that my object supports comparison checking.
Another option would be to keep the IComparable version, but add a second version that would handle only null types:
protected void SetProperty<T>(ref T currentPropertyValue, T newValue) where T : IComparable
protected void SetProperty(ref INullableValue currentPropertyValue, INullableValue newValue)
...except INullableValue no longer exists. This also produces a compile error:
protected void SetProperty(ref Nullable currentPropertyValue, Nullable newValue)
And this final attempt brings us back to the .Equals() problem:
protected void SetProperty(ref object currentPropertyValue, object newValue)
And so on and so on. The root problem here is that you cannot refer to a nullable type in a generic way in the August CTP, and you can't include nullable types in any group which must be IComparable.
I'm open to ideas, feel free to comment below.