Sunday, March 29, 2009

Workflow Foundation Bug

The first time I embraced the concept of a workflow was about 6 years ago, when designing ASM for microcontrolers (I miss working with the MCS-51). So, when the WF appeared, I was pretty enthusiastic and quickly started to study and investigate this new feature of the .NET Framework. By now, I can't hide the fact that I'm a huge fan of the WF.

But, of course, not everything is perfect and as a software product it has bugs. I came across one of them recently (related to the delay activity), here’s a little Microsoft article from the KB that describes the problem and a few other bugs.

Monday, March 23, 2009

From double to int through the heap

Twinkling through the WCF samples that Microsoft provides, I found a line of code that captured my attention. I was organizing the samples and one of them looked interesting, so I opened it and actually found a curious line. The sample is the WeaklyTypedJson (Ajax). But let me contextualize first.

Explicit cast from an object type to an integer is valid providing that the object holds an integer.

The above code, of course, implies one box and one unbox operation:

For those VB.NET users, even automatically implicit conversion is allowed when the Strict Option is set to off:

Now, when you have the code shown below, the conversion is also allowed (loosing precision):

So, if all the above statements are true, what happens to the code bellow?

At runtime, this will throw an InvalidCastException, stating that "Cannot unbox 'BoxedDouble' as an 'int'". This makes sense, because the CLR is trying to write in the stack a Double when the expected type is an Integer, and this violates one of the corner stones of the .NET framework, Type Safety. So, this takes us to the line of code that I found:

This is an operator overload to allow implicit conversion from JsonBaseType to Integer (InternalValue is of type object). The trick is actually quite nice: The unbox operation will be made using a double and then that double value type (on the stack) will be converted to an integer (loosing, of course, precision). Applying to my example:

And looking at the generated IL, we can see that there's an unbox operation and then a conversion:

This works fine, and it's actually a nice trick. I would write it, however, a little bit different: