ILGenerator.EmitCall(OpCode, MethodInfo, Type[]) Méthode

Définition

Place une instruction call ou callvirt sur le flux MSIL (Microsoft Intermediate Language) pour appeler une méthode varargs.

public:
 void EmitCall(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ methodInfo, cli::array <Type ^> ^ optionalParameterTypes);
public:
 virtual void EmitCall(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ methodInfo, cli::array <Type ^> ^ optionalParameterTypes);
public void EmitCall(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo methodInfo, Type[] optionalParameterTypes);
public virtual void EmitCall(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo methodInfo, Type[] optionalParameterTypes);
member this.EmitCall : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo * Type[] -> unit
abstract member EmitCall : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo * Type[] -> unit
override this.EmitCall : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo * Type[] -> unit
Public Sub EmitCall (opcode As OpCode, methodInfo As MethodInfo, optionalParameterTypes As Type())
Public Overridable Sub EmitCall (opcode As OpCode, methodInfo As MethodInfo, optionalParameterTypes As Type())

Paramètres

opcode
OpCode

Instruction MSIL à émettre sur le flux. Doit être Call, Callvirt ou Newobj.

methodInfo
MethodInfo

Méthode varargs à appeler.

optionalParameterTypes
Type[]

Types des arguments facultatifs si la méthode est une varargs méthode ; sinon, null.

Exceptions

opcode ne spécifie pas d’appel de méthode.

methodInfo a la valeur null.

La convention d’appel de la méthode n’est pas varargs, mais les types de paramètres facultatifs sont fournis. Cette exception est levée dans .NET Framework versions 1.0 et 1.1, dans les versions suivantes, aucune exception n’est levée.

Exemples

L’exemple de code suivant émet deux méthodes, une varargs méthode et une méthode qui appelle la varargs méthode. La EmitCall méthode est utilisée pour émettre l’appel à la varargs méthode.

using System;
using System.Reflection;
using System.Reflection.Emit;

class Example
{
    static void Main()
    {
        string name = "InMemory";

        AssemblyBuilder asmBldr =
           AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name),
              AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule(name);

        TypeBuilder tb = modBldr.DefineType("DemoVararg");

        // Create a vararg method with no return value and one
        // string argument. (The string argument type is the only
        // element of an array of Type objects.)
        //
        MethodBuilder mb1 = tb.DefineMethod("VarargMethod",
            MethodAttributes.Public | MethodAttributes.Static,
            CallingConventions.VarArgs,
            null,
            new Type[] { typeof(string) });

        ILGenerator il1 = mb1.GetILGenerator();

        LocalBuilder locAi = il1.DeclareLocal(typeof(ArgIterator));
        LocalBuilder locNext = il1.DeclareLocal(typeof(bool));

        Label labelCheckCondition = il1.DefineLabel();
        Label labelNext = il1.DefineLabel();

        // Load the fixed argument and print it.
        il1.Emit(OpCodes.Ldarg_0);
        il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }));

        // Load the address of the local variable represented by
        // locAi, which will hold the ArgIterator.
        il1.Emit(OpCodes.Ldloca_S, locAi);

        // Load the address of the argument list, and call the
        // ArgIterator constructor that takes an array of runtime
        // argument handles.
        il1.Emit(OpCodes.Arglist);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetConstructor(new Type[] { typeof(RuntimeArgumentHandle) }));

        // Enter the loop at the point where the remaining argument
        // count is tested.
        il1.Emit(OpCodes.Br_S, labelCheckCondition);

        // At the top of the loop, call GetNextArg to get the next
        // argument from the ArgIterator. Convert the typed reference
        // to an object reference and write the object to the console.
        il1.MarkLabel(labelNext);
        il1.Emit(OpCodes.Ldloca_S, locAi);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetNextArg", Type.EmptyTypes));
        il1.Emit(OpCodes.Call, typeof(TypedReference).GetMethod("ToObject"));
        il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(object) }));

        il1.MarkLabel(labelCheckCondition);
        il1.Emit(OpCodes.Ldloca_S, locAi);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetRemainingCount"));

        // If the remaining count is greater than zero, go to
        // the top of the loop.
        il1.Emit(OpCodes.Ldc_I4_0);
        il1.Emit(OpCodes.Cgt);
        il1.Emit(OpCodes.Stloc_1);
        il1.Emit(OpCodes.Ldloc_1);
        il1.Emit(OpCodes.Brtrue_S, labelNext);

        il1.Emit(OpCodes.Ret);

        // Create a method that contains a call to the vararg
        // method.
        MethodBuilder mb2 = tb.DefineMethod("CallVarargMethod",
            MethodAttributes.Public | MethodAttributes.Static,
            CallingConventions.Standard,
            typeof(void), Type.EmptyTypes);
        ILGenerator il2 = mb2.GetILGenerator();

        // Push arguments on the stack: one for the fixed string
        // parameter, and two for the list.
        il2.Emit(OpCodes.Ldstr, "Hello ");
        il2.Emit(OpCodes.Ldstr, "world ");
        il2.Emit(OpCodes.Ldc_I4, 2006);

        // Call the vararg method, specifying the types of the
        // arguments in the list.
        il2.EmitCall(OpCodes.Call, mb1, new Type[] { typeof(string), typeof(int) });

        il2.Emit(OpCodes.Ret);

        Type type = tb.CreateType();
        type.GetMethod("CallVarargMethod").Invoke(null, null);
    }
}

/* This code example produces the following output:

Hello world 2006
 */
Imports System.Reflection
Imports System.Reflection.Emit

Class Example
    
    Shared Sub Main() 

        Dim name As String = "InMemory"
        
        Dim asmBldr As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( _
            New AssemblyName(name), AssemblyBuilderAccess.Run)
        Dim modBldr As ModuleBuilder = asmBldr.DefineDynamicModule(name)
        
        Dim tb As TypeBuilder = modBldr.DefineType("DemoVararg")
        
        ' Create a vararg method with no return value and one 
        ' string argument. (The string argument type is the only
        ' element of an array of Type objects.)
        '
        Dim mb1 As MethodBuilder = tb.DefineMethod("VarargMethod", _
            MethodAttributes.Public Or MethodAttributes.Static, _
            CallingConventions.VarArgs, _
            Nothing, _
            New Type() {GetType(String)})
        
        Dim il1 As ILGenerator = mb1.GetILGenerator()
        
        Dim locAi As LocalBuilder = il1.DeclareLocal(GetType(ArgIterator))
        Dim locNext As LocalBuilder = il1.DeclareLocal(GetType(Boolean))
        
        Dim labelCheckCondition As Label = il1.DefineLabel()
        Dim labelNext As Label = il1.DefineLabel()
        
        ' Load the fixed argument and print it.
        il1.Emit(OpCodes.Ldarg_0)
        il1.Emit(OpCodes.Call, GetType(Console).GetMethod("Write", _
            New Type() {GetType(String)}))
        
        ' Load the address of the local variable represented by
        ' locAi, which will hold the ArgIterator.
        il1.Emit(OpCodes.Ldloca_S, locAi)
        
        ' Load the address of the argument list, and call the 
        ' ArgIterator constructor that takes an array of runtime
        ' argument handles. 
        il1.Emit(OpCodes.Arglist)
        il1.Emit(OpCodes.Call, GetType(ArgIterator).GetConstructor( _
            New Type() {GetType(RuntimeArgumentHandle)}))
        
        ' Enter the loop at the point where the remaining argument
        ' count is tested.
        il1.Emit(OpCodes.Br_S, labelCheckCondition)
        
        ' At the top of the loop, call GetNextArg to get the next 
        ' argument from the ArgIterator. Convert the typed reference
        ' to an object reference and write the object to the console.
        il1.MarkLabel(labelNext)
        il1.Emit(OpCodes.Ldloca_S, locAi)
        il1.Emit(OpCodes.Call, _
            GetType(ArgIterator).GetMethod("GetNextArg", Type.EmptyTypes))
        il1.Emit(OpCodes.Call, GetType(TypedReference).GetMethod("ToObject"))
        il1.Emit(OpCodes.Call, _
            GetType(Console).GetMethod("Write", New Type() {GetType(Object)}))
        
        il1.MarkLabel(labelCheckCondition)
        il1.Emit(OpCodes.Ldloca_S, locAi)
        il1.Emit(OpCodes.Call, _
            GetType(ArgIterator).GetMethod("GetRemainingCount"))
        
        ' If the remaining count is greater than zero, go to
        ' the top of the loop.
        il1.Emit(OpCodes.Ldc_I4_0)
        il1.Emit(OpCodes.Cgt)
        il1.Emit(OpCodes.Stloc_1)
        il1.Emit(OpCodes.Ldloc_1)
        il1.Emit(OpCodes.Brtrue_S, labelNext)
        
        il1.Emit(OpCodes.Ret)
        
        ' Create a method that contains a call to the vararg 
        ' method.
        Dim mb2 As MethodBuilder = tb.DefineMethod("CallVarargMethod", _
            MethodAttributes.Public Or MethodAttributes.Static, _
            CallingConventions.Standard, _
            Nothing, _
            Type.EmptyTypes)

        Dim il2 As ILGenerator = mb2.GetILGenerator()
        
        ' Push arguments on the stack: one for the fixed string
        ' parameter, and two for the list.
        il2.Emit(OpCodes.Ldstr, "Hello ")
        il2.Emit(OpCodes.Ldstr, "world ")
        il2.Emit(OpCodes.Ldc_I4, 2006)
        
        ' Call the vararg method, specifying the types of the 
        ' arguments in the list.
        il2.EmitCall(OpCodes.Call, mb1, _
            New Type() {GetType(String), GetType(Integer)})
        
        il2.Emit(OpCodes.Ret)
        
        Dim myType As Type = tb.CreateType()
        myType.GetMethod("CallVarargMethod").Invoke(Nothing, Nothing)
    
    End Sub 
End Class 

' This code example produces the following output:
'
'Hello world 2006
'

Remarques

La EmitCall méthode est utilisée pour émettre des appels à varargs des méthodes, car il n’existe aucune surcharge de la Emit méthode qui spécifie les types de paramètres des arguments de variable.

Pour émettre des appels à des méthodes qui n’utilisent pas la VarArgs convention d’appel, utilisez la surcharge de Emit(OpCode, MethodInfo) méthode.

La EmitCall méthode ne lève pas d’exception lorsque les types de paramètres facultatifs sont spécifiés pour une méthode qui n’est pas varargs. InvalidProgramException est levée lorsque l’appel est exécuté.

S’applique à