Sunday, April 30, 2006

Differences between C# generics and other implementations

C++ templates differ significantly from C# generics. Where C# generics are compiled into IL, causing specialization to occur intelligently at run-time for each value type and once only for reference types, C++ templates are essentially code expansion macros that generate a specialized type for each type parameter supplied to a template. So, when the C++ compiler encounters a template, say a Stack of integers, it will expand the template code into a Stack class that contains integers internally as its native type. Regardless of whether the type parameter is a value or reference type, unless the linker is specifically designed to reduce code bloat, the C++ compiler will create a specialized class each time, resulting in a significant increase in code bloat over C# generics.

Moreover, C++ templates cannot define constraints. C++ templates may only define constraints implicitly by simply using a member that might or might not belong to the type parameter. If the member does exist in the type parameter that is eventually passed to the generic class, the program will work properly. If the member does not exist in the type parameter, the program will fail and a cryptic error message will likely be returned. Because C# generics can declare constraints and are strongly typed, these potential errors do not exist.

Meanwhile, Sun has proposed the addition of generics in the next version of the Java language, codenamed Tiger. Sun has chosen an implementation that does not require modifying the Java Virtual Machine. As such, Sun is faced with implementing generics on an unmodified virtual machine.

The proposed Java implementation uses similar syntax to templates in C++ and generics in C#, including type parameters and constraints. But, because it treats value types differently than reference types, the unmodified Java Virtual Machine will not be able to support generics for value types. As such, generics in Java will gain no execution efficiency. Indeed, the Java compiler will inject automatic downcasts from the specified constraint, if one is declared, or the base Object type, if a constraint is not declared, whenever it needs to return data. Further, the Java compiler will generate a single specialized type at compile-time that it will then use to instantiate any constructed type. Finally, because the Java Virtual Machine will not support generics natively, there will be no way to ascertain the type parameter for an instance of a generic type at run-time and other uses of reflection will be severely limited.

0 Comments:

Post a Comment

<< Home