As I understand it, C#/.Net generics support some degree of reification. So, if I have the following code:
List<int> list = new List<int>();
list.Add(1);
Will the value 1 be autoboxed or will the 'list' object handle primitive ints efficiently?
As I understand it, C#/.Net generics support some degree of reification. So, if I have the following code:
List<int> list = new List<int>();
list.Add(1);
Will the value 1 be autoboxed or will the 'list' object handle primitive ints efficiently?
.NET generics are getting specialized for structs, thus there is no boxing required in your case. Note that there is no need for casting too anyway.
No, it won't be boxed. At execution time, the backing array for the List<int>
will genuinely be an int[]
. Note that this isn't just the case with genuine primitive types - List<T>
won't box values of any value type (assuming it's been declared as List<Guid>
etc rather than List<object>
).
Basically, generics in .NET keep a lot more of their information than they do in Java - the CLR natively understands generics and deals with them appropriately, rather than in Java where the JVM is pretty much ignorant of them.
For example, if you write:
object list = new List<string>();
Type type = list.GetType();
Then type
will be equal to typeof(List<string>)
- which is then different to (say) List<Guid>
etc.
The int
values will not be boxed within the list. This is one of the beauties with generics, that the compiler (more specifically the JIT-compiler, I believe) will construct a typed version of the List<>
class, rather than storing the values as object
. So it does not only enforce type safety through the exposed methods and properties, but it is genuinely typed in all aspects.
As others have noted, the jitter generates new code for every construction involving a new value type. An interesting point not yet mentioned so far is that the jitter will generate code once for a reference type construction and re-use that for every reference type. The code for List<object>
is exactly the same as the code for List<string>
.
That might sound crazy, but remember, generics are not templates. By the time the code for the generic method body IL is emitted, overload resolution and other relevant semantic analysis is already done by the C# compiler.