The following table lists the instruction's hexadecimal and Microsoft Intermediate Language (MSIL) assembly format, along with a brief reference summary:
28 < T > |
call methodDesc |
Call the method described by methodDesc. |
The stack transitional behavior, in sequential order, is:
[The 'ordered' type of list has not been implemented in the ECMA stylesheet.]The call instruction calls the method indicated by the method descriptor passed with the instruction. The method descriptor is a metadata token that indicates the method to call and the number, type, and order of the arguments that have been placed on the stack to be passed to that method as well as the calling convention to be used. The call instruction can be immediately preceded by a tail (OpCodes.Tailcall) prefix instruction to specify that the current method state should be released before transferring control. If the call transfers control to a method of higher trust than the origin method, the stack frame is not released. Instead, the execution continues silently as if the tail had not been supplied. The metadata token carries sufficient information to determine whether the call is to a static method, an instance method, a virtual method, or a global function. In all of these cases the destination address is determined entirely from the method descriptor (contrast this with the OpCodes.Callvirt instruction for calling virtual methods, where the destination address also depends upon the runtime type of the instance reference pushed before the OpCodes.Callvirt).
The arguments are placed on the stack in left-to-right order. That is, the first argument is computed and placed on the stack, then the second argument, then the third, until all necessary arguments are atop the stack in descending order. There are three important special cases:
1. Calls to an instance (or virtual) method must push that instance reference before any of the user-visible arguments. The instance reference must not be a null reference. The signature carried in the metadata does not contain an entry in the parameter list for the this pointer; instead, it uses a bit to indicate whether the method requires passing the this pointer.
2. It is valid to call a virtual method using call (rather than callvirt); this indicates that the method is to be resolved using the class specified by method rather than as specified dynamically from the object being invoked.
3. Note that a delegate's Invoke method can be called with either the call or callvirt instruction.
System.Security.SecurityException may be thrown if system security does not grant the caller access to the called method. The security check may occur when the Microsoft Intermediate Language (MSIL) instructions are converted to native code rather than at run time.
When calling methods of System.Object on value types, consider using the constrained prefix with the callvirt instruction instead of emitting a call instruction. This removes the need to emit different IL depending on whether or not the value type overrides the method, avoiding a potential versioning problem. Consider using the constrained prefix when invoking interface methods on value types, since the value type method implementing the interface method can be changed using a MethodImpl. These issues are described in more detail in the OpCodes.Constrained opcode.
The following ILGenerator.Emit(OpCode) method overloads can use the call opcode:
ILGenerator.Emit(OpCode, MethodInfo)
ILGenerator.EmitCall(OpCode, MethodInfo, Type[])
The ILGenerator.EmitCall(OpCode, System.Reflection.MethodInfo, Type[]) method is provided for varargs calls. Use the ILGenerator.Emit(OpCode) method for normal calls.