ILGenerator.Emit Method

Definition

Puts an instruction onto the Microsoft Intermediate Language (MSIL) stream for the just-in-time (JIT) compiler.

Overloads

Emit(OpCode, LocalBuilder)

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

Emit(OpCode, Type)

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

Emit(OpCode, String)

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

Emit(OpCode, Single)

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SByte)

Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, MethodInfo)

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

Emit(OpCode, SignatureHelper)

Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Label[])

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, FieldInfo)

Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, ConstructorInfo)

Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int64)

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int32)

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int16)

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Double)

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Byte)

Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode)

Puts the specified instruction onto the stream of instructions.

Emit(OpCode, Label)

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, LocalBuilder)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

local
LocalBuilder

A local variable.

Exceptions

The parent method of the local parameter does not match the method associated with this ILGenerator.

local is null.

opcode is a single-byte instruction, and local represents a local variable with an index greater than Byte.MaxValue.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Type)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, Type cls);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

cls
Type

A Type.

Exceptions

cls is null.

Remarks

The instruction values are defined in the OpCodes enumeration. The location of cls is recorded so that the token can be patched if necessary when persisting the module to a portable executable (PE) file.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, String)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, string str);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

str
String

The String to be emitted.

Remarks

The instruction values are defined in the OpCodes enumeration. The location of str is recorded for future fixups if the module is persisted to a portable executable (PE) file.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Single)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, float arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

arg
Single

The Single argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, SByte)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Important

This API is not CLS-compliant.

Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
[System.CLSCompliant(false)]
public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

arg
SByte

The character argument pushed onto the stream immediately after the instruction.

Attributes

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, MethodInfo)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

meth
MethodInfo

A MethodInfo representing a method.

Exceptions

meth is null.

meth is a generic method for which the IsGenericMethodDefinition property is false.

Remarks

The instruction values are defined in the OpCodes enumeration.

The location of meth is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

If meth represents a generic method, it must be a generic method definition. That is, its MethodInfo.IsGenericMethodDefinition property must be true.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, SignatureHelper)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

signature
SignatureHelper

A helper for constructing a signature token.

Exceptions

signature is null.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Label[])

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

labels
Label[]

The array of label objects to which to branch from this location. All of the labels will be used.

Exceptions

con is null. This exception is new in the .NET Framework 4.

Examples

The code sample below illustrates the creation of a dynamic method with a jump table. The jump table is built using an array of Label.

C#
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo
{
   public static Type BuildMyType()
   {
    AppDomain myDomain = Thread.GetDomain();
    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = "MyDynamicAssembly";

    AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
                        myAsmName,
                        AssemblyBuilderAccess.Run);
    ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
                        "MyJumpTableDemo");

    TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
                            TypeAttributes.Public);
    MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
                             MethodAttributes.Public |
                             MethodAttributes.Static,
                                             typeof(string),
                                             new Type[] {typeof(int)});

    ILGenerator myIL = myMthdBuilder.GetILGenerator();

    Label defaultCase = myIL.DefineLabel();	
    Label endOfMethod = myIL.DefineLabel();	

    // We are initializing our jump table. Note that the labels
    // will be placed later using the MarkLabel method.

    Label[] jumpTable = new Label[] { myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel() };

    // arg0, the number we passed, is pushed onto the stack.
    // In this case, due to the design of the code sample,
    // the value pushed onto the stack happens to match the
    // index of the label (in IL terms, the index of the offset
    // in the jump table). If this is not the case, such as
    // when switching based on non-integer values, rules for the correspondence
    // between the possible case values and each index of the offsets
    // must be established outside of the ILGenerator.Emit calls,
    // much as a compiler would.

    myIL.Emit(OpCodes.Ldarg_0);
    myIL.Emit(OpCodes.Switch, jumpTable);
    
    // Branch on default case
    myIL.Emit(OpCodes.Br_S, defaultCase);

    // Case arg0 = 0
    myIL.MarkLabel(jumpTable[0]);
    myIL.Emit(OpCodes.Ldstr, "are no bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 1
    myIL.MarkLabel(jumpTable[1]);
    myIL.Emit(OpCodes.Ldstr, "is one banana");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 2
    myIL.MarkLabel(jumpTable[2]);
    myIL.Emit(OpCodes.Ldstr, "are two bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 3
    myIL.MarkLabel(jumpTable[3]);
    myIL.Emit(OpCodes.Ldstr, "are three bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 4
    myIL.MarkLabel(jumpTable[4]);
    myIL.Emit(OpCodes.Ldstr, "are four bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Default case
    myIL.MarkLabel(defaultCase);
    myIL.Emit(OpCodes.Ldstr, "are many bananas");

    myIL.MarkLabel(endOfMethod);
    myIL.Emit(OpCodes.Ret);
    
    return myTypeBuilder.CreateType();
   }

   public static void Main()
   {
    Type myType = BuildMyType();
    
    Console.Write("Enter an integer between 0 and 5: ");
    int theValue = Convert.ToInt32(Console.ReadLine());

    Console.WriteLine("---");
    Object myInstance = Activator.CreateInstance(myType, new object[0]);	
    Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
                               BindingFlags.InvokeMethod,
                               null,
                               myInstance,
                               new object[] {theValue}));
   }
}

Remarks

Emits a switch table.

The instruction values are defined in the OpCodes enumeration.

Labels are created using DefineLabel and their location within the stream is fixed by using MarkLabel. If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode must represent a branch instruction. Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, FieldInfo)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

field
FieldInfo

A FieldInfo representing a field.

Remarks

The instruction values are defined in the OpCodes enumeration. The location of field is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, ConstructorInfo)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
C#
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

con
ConstructorInfo

A ConstructorInfo representing a constructor.

Attributes

Exceptions

con is null. This exception is new in the .NET Framework 4.

Remarks

The instruction values are defined in the OpCodes enumeration.

The location of con is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Int64)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, long arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

arg
Int64

The numerical argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Int32)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, int arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

arg
Int32

The numerical argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Int16)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, short arg);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

arg
Int16

The Int argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Double)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, double arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream. Defined in the OpCodes enumeration.

arg
Double

The numerical argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Byte)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, byte arg);

Parameters

opcode
OpCode

The MSIL instruction to be put onto the stream.

arg
Byte

The character argument pushed onto the stream immediately after the instruction.

Remarks

The instruction values are defined in the OpCodes enumeration.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the stream of instructions.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode);

Parameters

opcode
OpCode

The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.

Examples

The code sample below demonstrates the use of Emit to generate MSIL output via an instance of ILGenerator.

C#
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo
{
   public static Type BuildMyType()
   {
    AppDomain myDomain = Thread.GetDomain();
    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = "MyDynamicAssembly";

    AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
                        myAsmName,
                        AssemblyBuilderAccess.Run);
    ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
                        "MyJumpTableDemo");

    TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
                            TypeAttributes.Public);
    MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
                             MethodAttributes.Public |
                             MethodAttributes.Static,
                                             typeof(string),
                                             new Type[] {typeof(int)});

    ILGenerator myIL = myMthdBuilder.GetILGenerator();

    Label defaultCase = myIL.DefineLabel();	
    Label endOfMethod = myIL.DefineLabel();	

    // We are initializing our jump table. Note that the labels
    // will be placed later using the MarkLabel method.

    Label[] jumpTable = new Label[] { myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel() };

    // arg0, the number we passed, is pushed onto the stack.
    // In this case, due to the design of the code sample,
    // the value pushed onto the stack happens to match the
    // index of the label (in IL terms, the index of the offset
    // in the jump table). If this is not the case, such as
    // when switching based on non-integer values, rules for the correspondence
    // between the possible case values and each index of the offsets
    // must be established outside of the ILGenerator.Emit calls,
    // much as a compiler would.

    myIL.Emit(OpCodes.Ldarg_0);
    myIL.Emit(OpCodes.Switch, jumpTable);
    
    // Branch on default case
    myIL.Emit(OpCodes.Br_S, defaultCase);

    // Case arg0 = 0
    myIL.MarkLabel(jumpTable[0]);
    myIL.Emit(OpCodes.Ldstr, "are no bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 1
    myIL.MarkLabel(jumpTable[1]);
    myIL.Emit(OpCodes.Ldstr, "is one banana");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 2
    myIL.MarkLabel(jumpTable[2]);
    myIL.Emit(OpCodes.Ldstr, "are two bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 3
    myIL.MarkLabel(jumpTable[3]);
    myIL.Emit(OpCodes.Ldstr, "are three bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 4
    myIL.MarkLabel(jumpTable[4]);
    myIL.Emit(OpCodes.Ldstr, "are four bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Default case
    myIL.MarkLabel(defaultCase);
    myIL.Emit(OpCodes.Ldstr, "are many bananas");

    myIL.MarkLabel(endOfMethod);
    myIL.Emit(OpCodes.Ret);
    
    return myTypeBuilder.CreateType();
   }

   public static void Main()
   {
    Type myType = BuildMyType();
    
    Console.Write("Enter an integer between 0 and 5: ");
    int theValue = Convert.ToInt32(Console.ReadLine());

    Console.WriteLine("---");
    Object myInstance = Activator.CreateInstance(myType, new object[0]);	
    Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
                               BindingFlags.InvokeMethod,
                               null,
                               myInstance,
                               new object[] {theValue}));
   }
}

Remarks

If the opcode parameter requires an argument, the caller must ensure that the argument length matches the length of the declared parameter. Otherwise, results will be unpredictable. For example, if the Emit instruction requires a 2-byte operand and the caller supplies a 4-byte operand, the runtime will emit two additional bytes to the instruction stream. These extra bytes will be Nop instructions.

The instruction values are defined in OpCodes.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1

Emit(OpCode, Label)

Source:
ILGenerator.cs
Source:
ILGenerator.cs
Source:
ILGenerator.cs

Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

C#
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
C#
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);

Parameters

opcode
OpCode

The MSIL instruction to be emitted onto the stream.

label
Label

The label to which to branch from this location.

Examples

The code sample below illustrates the creation of a dynamic method with a jump table. The jump table is built using an array of Label.

C#
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo
{
   public static Type BuildMyType()
   {
    AppDomain myDomain = Thread.GetDomain();
    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = "MyDynamicAssembly";

    AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
                        myAsmName,
                        AssemblyBuilderAccess.Run);
    ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
                        "MyJumpTableDemo");

    TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
                            TypeAttributes.Public);
    MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
                             MethodAttributes.Public |
                             MethodAttributes.Static,
                                             typeof(string),
                                             new Type[] {typeof(int)});

    ILGenerator myIL = myMthdBuilder.GetILGenerator();

    Label defaultCase = myIL.DefineLabel();	
    Label endOfMethod = myIL.DefineLabel();	

    // We are initializing our jump table. Note that the labels
    // will be placed later using the MarkLabel method.

    Label[] jumpTable = new Label[] { myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel(),
                      myIL.DefineLabel() };

    // arg0, the number we passed, is pushed onto the stack.
    // In this case, due to the design of the code sample,
    // the value pushed onto the stack happens to match the
    // index of the label (in IL terms, the index of the offset
    // in the jump table). If this is not the case, such as
    // when switching based on non-integer values, rules for the correspondence
    // between the possible case values and each index of the offsets
    // must be established outside of the ILGenerator.Emit calls,
    // much as a compiler would.

    myIL.Emit(OpCodes.Ldarg_0);
    myIL.Emit(OpCodes.Switch, jumpTable);
    
    // Branch on default case
    myIL.Emit(OpCodes.Br_S, defaultCase);

    // Case arg0 = 0
    myIL.MarkLabel(jumpTable[0]);
    myIL.Emit(OpCodes.Ldstr, "are no bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 1
    myIL.MarkLabel(jumpTable[1]);
    myIL.Emit(OpCodes.Ldstr, "is one banana");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 2
    myIL.MarkLabel(jumpTable[2]);
    myIL.Emit(OpCodes.Ldstr, "are two bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 3
    myIL.MarkLabel(jumpTable[3]);
    myIL.Emit(OpCodes.Ldstr, "are three bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Case arg0 = 4
    myIL.MarkLabel(jumpTable[4]);
    myIL.Emit(OpCodes.Ldstr, "are four bananas");
    myIL.Emit(OpCodes.Br_S, endOfMethod);

    // Default case
    myIL.MarkLabel(defaultCase);
    myIL.Emit(OpCodes.Ldstr, "are many bananas");

    myIL.MarkLabel(endOfMethod);
    myIL.Emit(OpCodes.Ret);
    
    return myTypeBuilder.CreateType();
   }

   public static void Main()
   {
    Type myType = BuildMyType();
    
    Console.Write("Enter an integer between 0 and 5: ");
    int theValue = Convert.ToInt32(Console.ReadLine());

    Console.WriteLine("---");
    Object myInstance = Activator.CreateInstance(myType, new object[0]);	
    Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
                               BindingFlags.InvokeMethod,
                               null,
                               myInstance,
                               new object[] {theValue}));
   }
}

Remarks

The instruction values are defined in the OpCodes enumeration.

Labels are created using DefineLabel, and their location within the stream is fixed by using MarkLabel. If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode must represent a branch instruction. Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Applies to

.NET 9 and other versions
Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1