Free mag vol1 | Page 742

CHAPTER 18  UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES In general, the types of the System.Reflection.Emit namespace allow you to represent raw CIL tokens programmatically during the construction of your dynamic assembly. You will see many of these members in the example that follows; however, the ILGenerator type is worth checking out straightaway. The Role of the System.Reflection.Emit.ILGenerator As its name implies, the ILGenerator type’s role is to inject CIL opcodes into a given type member. However, you cannot directly create ILGenerator objects, as this type has no public constructors; rather, you receive an ILGenerator type by calling specific methods of the builder-centric types (such as the MethodBuilder and ConstructorBuilder types). For example: // Obtain an ILGenerator from a ConstructorBuilder // object named "myCtorBuilder". ConstructorBuilder myCtorBuilder = new ConstructorBuilder(/* ...various args... */); ILGenerator myCILGen = myCtorBuilder.GetILGenerator(); Once you have an ILGenerator in your hands, you are then able to emit the raw CIL opcodes using any number of methods. Table 18-9 documents some (but not all) methods of ILGenerator. Table 18-9. Various Methods of ILGenerator Method Meaning in Life BeginCatchBlock() Begins a catch block BeginExceptionBlock() Begins an exception block for a nonfiltered exception BeginFinallyBlock() Begins a finally block BeginScope() Begins a lexical scope DeclareLocal() Declares a local variable DefineLabel() Declares a new label Emit() Is overloaded numerous times to allow you to emit CIL opcodes EmitCall() Pushes a call or callvirt opcode into the CIL stream EmitWriteLine() Emits a call to Console.WriteLine() with different types of values EndExceptionBlock() Ends an exception block EndScope() Ends a le X