tags:

views:

114

answers:

2

Allegedly, the native code is shared for instantiated generic types when it is instantiated with a reference type, but not for value types.

Why is that? would someone explain the in-depth details?

To make more concrete:

class MyGenericType{

}

 MyGenericType<string> and MyGenericType<Shape>

will have only one code generated, whereas

 MyGenericType<int> and MyGenericType<long>

will NOT, hence it begs the question if using reference types is more efficient --

MyGenericType<int> vs. MyGenericType<SomeIntegerWrapper>

Thanks

+1  A: 

Technically, at a lower level, all reference types are pointers and therefore, have the same size and characteristics. There is no need for the runtime to build separate native code for reference types. Value types can have different sizes, so a single native code cannot deal with all of them.

Mehrdad Afshari
+3  A: 

First, to correct a fallacy in the question, int and System.Int32 are synonymous. MyGenericType<int> and MyGenericType<Int32> are exactly the same type.

Secondly, to address the question (and slightly expand on Mehrdad's answer): consider what the CLR needs to know about a type. It includes:

  • The size of a value of that type (i.e. if you have a variable of some type, how much space will that memory need?)
  • How to treat the value in terms of garbage collection: is it a reference to an object, or a value which may in turn contain other references?

For all reference types, the answers to these questions are the same. The size is just the size of a pointer, and the value is always just a reference (so if the variable is considered a root, the GC needs to recursively descend into it).

For value types, the answers can vary significantly. For instance, consider:

struct First
{
    int x;
    object y;
}

struct Second
{
    object a;
    int b;
}

When the GC looks at some memory, it needs to know the difference between First and Second so it can recurse into y and a but not x and b. I believe this information is generated by the JIT. Now consider the information for List<First> and List<Second> - it differs, so the JIT needs to treat the two differently.

Apologies if this isn't as clear as it might be - this is somewhat deep stuff, and I'm not as hot on CLR details as I might be.

Jon Skeet