- newobj <constructor>: This creates an uninitialized object of the type specified via the constructor. If the object is a value type (struct etc.), it is created on the stack. If it is a reference typ (class etc.) it lands on the heap. You always know the type from the CIL code, so you can tell easily where the allocation occurs.
- newarr <element type>: This instruction creates a new array on the heap. The type of elements is specified in the a parameter.
- box <value type token>: This very specialized instruction performs boxing, which we already discussed in the first part of this series.
Let's look at a rather contrived method that performs all three types of allocations.
void SomeMethod() { object[] myArray = new object[1]; myArray[0] = 5; Dictionary<int, int> myDict = new Dictionary<int, int>(); myDict[4] = 6; foreach (int key in myDict.Keys) Console.WriteLine(key); }
The amount of CIL code generated from these few lines is huge, so I'll just show the key parts here:
IL_0001: newarr [mscorlib]System.Object ... IL_000a: box [mscorlib]System.Int32 ... IL_0010: newobj instance void class [mscorlib]System. Collections.Generic.Dictionary'2<int32, int32>::.ctor() ... IL_001f: callvirt instance class [mscorlib]System. Collections.Generic.Dictionary`2/KeyCollection<!0, !1> class [mscorlib]System.Collections.Generic.Dictionary`2<int32, int32>::get_Keys()
No comments:
Post a Comment