C# FAQ: What are the differences between CSharp and Java generics

Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio


Jump to: navigation, search
CSharp-Online.NET:FAQs
edit

What are the differences between C# and Java generics?

Both the C# and Java languages support mechanisms for creating strongly typed data structures with the specific types being unknown at compile time—i.e. generics. Before the invention of generics, a similar effect could be achieved by specifying the object type within the data structure as type Object; and, specific types could be cast at runtime. But, this technique has several major problems—e.g. bloated code, no type safety, poor performance.

Both C# and Java generics are similar in concept to C++ templates; however the implementation differs.

In Java, the generic capability is implemented via a technique called type erasure. This means that generic type information exists only at compile time. Afterwards, the compiler replaces any type declarations with Object. Finally, the compiler inserts casts in the appropriate spots. This Java compiler trick supports complete interoperability between new generic code and old legacy code. One shortcoming of type erasure is that generic type information is unavailable at runtime. Another shortcoming is that generic data structure types must be declared using only objects—no primitive data types. (For example, Stack<Integer> must be used instead of Stack<int>.)

C# contains explicit support for generics via the .NET Common Language Runtime (CLR). When a generic type is compiled, the generated Intermediate Language (IL) has place holders for certain types.

When the first reference is made to a generic type at runtime—e.g. Stack<int>—, the CLR causes the JIT compiler to instantiate a new type which replaces the generic type parameters with the specific type—e.g. replacing Stack<T> with Stack<int>. Otherwise, the specific type generated on the initial reference will be returned.

If the requested type is a reference type—not a value type—, then Object will replace the generic type parameter. When accessing the type, the CLR performs no internal casting.

Sometimes, a method is required which can operate on data structures containing any type—versus those that contain a specific type—but which still uses strong typing. Whereas the Java system implements this using wildcard types, this can be specified in C# with a feature called generic type inferencing. Both approaches yield the same results.

Both the C# and Java languages allow the specification of generic type constraints. C# features three types of generic type constraint:

  • default constructor constraint notifies the C# compiler that a generic type parameter exposes a public default constructor;
  • derivation constraint notifies the C# compiler that a generic type parameter subclasses a base type—e.g. a certain base class or interface;
  • reference or value type constraint restricts the generic type parameter to either a reference or a value type respectively.

The Java language supports only the derivation constraint.

In support of generic code, C# provides the default operator to return the default type value. Whereas the default value of reference types is null, value types are zero filled.

See also



Personal tools