How does C# generics affect collections with primitives
Asked Answered
L

4

12

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?

Lavinalavine answered 18/9, 2010 at 10:39 Comment(0)
F
21

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.

Faint answered 18/9, 2010 at 10:41 Comment(0)
F
5

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.

Fungicide answered 18/9, 2010 at 10:42 Comment(0)
Y
5

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.

Yapon answered 18/9, 2010 at 14:17 Comment(1)
However, a call to, say, new T[10] will still create the right type of array, even for reference types.Faint
M
3

.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.

Moraceous answered 18/9, 2010 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.