Wednesday, January 16, 2013

bool versus Boolean

Both in Java and in .NET there is a difference between the primitive value types (such as bool, int, etc.) and the boxed versions of these types (java.lang.Boolean). The reason for that is simple: you want to use fast value types but sometimes you have to use them as an object on the heap.

This article explains how dot42 maps the boxed java types into the .NET world.

The problem

The main difficulty in this mapping is the following: Java has both primitive types and boxed types publicly available, but .NET has not. In .NET the boxed types are "internal".
The Android API uses both the primitive type as well as the boxed types in method parameters, field types etc. So we still have to make a difference between a bool parameter of some Android method and a Boolean parameter. Mapping both to the same primitive .NET type is no option, because you have to express the 'null' possibility and it breaks dot42 at runtime. So how did we do this.

Our options

We had a couple of options:
  1. Import the Java boxed types as normal .NET classes. This means that there would be a Boolean class, an Integer class and so on.
  2. Use Nullable<T>. This .NET construct is intended for extending value types with the ability to be "null".
  3. Use another generic class, e.g. Boxed<T>.
The third option was dismissed quickly, because it does not "fit" the mind of the C# programmer, nor does it fit the Java world.

The first option seems like the most obvious choice to make. It is a direct mapping from the Java world to the .NET world. The downside of this option is that it is very "Java" like, therefore it is less recognizable for C# programmers.
The second option eventually seemed like the best choice for dot42. It is a well known feature of C# and it expresses exactly what you want: A value that is either an actual primitive value or "null".

The implementation

Now that we chose the Nullable<T> option for dot42, we had to make it work. We have used a combination of compiler generated code and actual C# source code for the dot42.dll.

All (almost all) uses of boxed types (such as Boolean) in the Android API now map on a nullable type in dot42.dll. Our compiler (that compiles IL into Dex) implements most of the members of Nullable<T> using custom Dex code. For example Nullable<bool>.HasValue is compiled to a null check on the java.lang.Boolean instance that is used to implement it. It also converts Nullable<T> back to the original boxed types. For example Nullable<bool> (or bool?) is converted to java.lang.Boolean.

With this mapping in place, we have an API that matches the intend of the Android API methods and we have a construct that is well known to C# programmers.

No comments:

Post a Comment