Compartir a través de


TypeBuilder.DefineMethodOverride Method

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Updated: December 2010

Specifies a given method body that implements a given method declaration, potentially with a different name.

Namespace:  System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

Syntax

'Declaration
<SecuritySafeCriticalAttribute> _
Public Sub DefineMethodOverride ( _
    methodInfoBody As MethodInfo, _
    methodInfoDeclaration As MethodInfo _
)
[SecuritySafeCriticalAttribute]
public void DefineMethodOverride(
    MethodInfo methodInfoBody,
    MethodInfo methodInfoDeclaration
)

Parameters

Exceptions

Exception Condition
ArgumentException

methodInfoBody does not belong to this class.

ArgumentNullException

methodInfoBody or methodInfoDeclaration is nulla null reference (Nothing in Visual Basic).

InvalidOperationException

The type was previously created using CreateType.

-or-

The declaring type of methodInfoBody is not the type represented by this TypeBuilder.

Remarks

Do not use this method to emit method overrides or interface implementations. To override a method of a base class or to implement a method of an interface, simply emit a method with the same name and signature as the method to be overridden or implemented, as demonstrated in the code example.

The DefineMethodOverride method is used when a method body and a method declaration have different names. For example, a class might override a base class method and also provide a separate implementation for an interface member with the same name, as demonstrated in the code example.

DefineMethodOverride defines a methodimpl, which consists of a pair of metadata tokens. One token points to an implementation, and the other token points to a declaration that the body implements. The body must be defined on the type the method impl is defined on, and the body must be virtual (Overridable in Visual Basic). The declaration can be made to a method defined on an interface implemented by the type, a method on a derived class, or a method defined in the type. If the declaration is on an interface only, the slot defined for the interface is altered. If the declaration is made to a method on a base type, the slot for the method is overridden and any duplicates for the overridden method are also replaced. The overridden method cannot be the actual method that is declared. If the method is on the same type, the slot is replaced and any duplicates for the replaced methods are overridden.

NoteNote:

For more information about method impls, see MethodImpl in the ECMA Partition II Metadata documentation. The documentation is available online; see ECMA C# and Common Language Infrastructure Standards on MSDN and Standard ECMA-335 - Common Language Infrastructure (CLI) on the Ecma International Web site.

Important noteImportant Note:

After the DefineMethodOverride method is called, some features of methodInfoBody cannot be changed. For example, you cannot apply an attribute to a generic type parameter of methodInfoBody by using the SetGenericParameterAttributes method. If you must use the DefineMethodOverride method, do so after all characteristics of methodInfoBody have been defined.

Examples

The following example contains an interface I with a method M(), a base class A that implements the interface, and a derived class C that overrides the base class implementation of M() and also provides a separate explicit implementation of I.M().

The main() method of the code example shows how to emit the derived class C. The override of A.M() is accomplished simply by emitting a method M() with the same signature. However, to provide a separate implementation of I.M(), you must define a method body and then use the DefineMethodOverride method to associate that method body with a MethodInfo representing I.M(). The name of the method body does not matter.

The code example creates an instance of the emitted class. It obtains a MethodInfo object for I.M(), and uses it to invoke the emitted class's explicit interface implementation. It then obtains a MethodInfo object for A.M(), and uses it to invoke the emitted class's override of that method.

Imports System.Reflection
Imports System.Reflection.Emit

Public Interface I
   Function M() As String
End Interface

Public Class A
   Public Overridable Function M() As String
      Return "In method A.M" 
   End Function
End Class

' The object of this code example is to emit code equivalent to
' the following C# code:
'
Public Class C
   Inherits A
   Implements I

   Public Overrides Function M() As String
      Return "Overriding A.M from C.M" 
   End Function

   ' In order to provide a different implementation from C.M when 
   ' emitting the following explicit interface implementation, 
   ' it is necessary to use a MethodImpl.
   '
   Private Function IM() As String Implements I.M
      Return "The I.M implementation of C" 
   End Function
End Class

Class Example

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)

      Dim name As String = "DefineMethodOverrideExample"
      Dim asmName As New AssemblyName(name)
      Dim ab As AssemblyBuilder = _
          AppDomain.CurrentDomain.DefineDynamicAssembly( _
              asmName, AssemblyBuilderAccess.Run)
      Dim mb As ModuleBuilder = ab.DefineDynamicModule(name)

      Dim tb As TypeBuilder = _
          mb.DefineType("C", TypeAttributes.Public, GetType(A))
      tb.AddInterfaceImplementation(GetType(I))

      ' Build the method body for the explicit interface 
      ' implementation. The name used for the method body 
      ' can be anything. Here, it is the name of the method,
      ' qualified by the interface name.
      '
      Dim mbIM As MethodBuilder = _
          tb.DefineMethod("I.M", _
          MethodAttributes.Private Or MethodAttributes.HideBySig Or _
              MethodAttributes.NewSlot Or MethodAttributes.Virtual Or _
              MethodAttributes.Final, _
          GetType(String), _
          Type.EmptyTypes)
      Dim il As ILGenerator = mbIM.GetILGenerator()
      il.Emit(OpCodes.Ldstr, "The I.M implementation of C")
      il.Emit(OpCodes.Ret)

      ' DefineMethodOverride is used to associate the method 
      ' body with the interface method that is being implemented.
      '
      tb.DefineMethodOverride(mbIM, GetType(I).GetMethod("M"))

      Dim mbM As MethodBuilder = tb.DefineMethod("M", _
          MethodAttributes.Public Or MethodAttributes.ReuseSlot Or _
              MethodAttributes.Virtual Or MethodAttributes.HideBySig, _
          GetType(String), _
          Type.EmptyTypes)
      il = mbM.GetILGenerator()
      il.Emit(OpCodes.Ldstr, "Overriding A.M from C.M")
      il.Emit(OpCodes.Ret)

      Dim tc As Type = tb.CreateType()

      Dim test As Object = Activator.CreateInstance(tc)

      Dim mi As MethodInfo = GetType(I).GetMethod("M")
      outputBlock.Text &= mi.Invoke(test, Nothing) & vbLf

      mi = GetType(A).GetMethod("M")
      outputBlock.Text &= mi.Invoke(test, Nothing) & vbLf

   End Sub
End Class

' This code example produces the following output:
'
'The I.M implementation of C
'Overriding A.M from C.M
' 
using System;
using System.Reflection;
using System.Reflection.Emit;

public interface I
{
   string M();
}

public class A
{
   public virtual string M() { return "In method A.M"; }
}

// The object of this code example is to emit code equivalent to
// the following C# code:
//
public class C : A, I
{
   public override string M()
   {
      return "Overriding A.M from C.M";
   }

   // In order to provide a different implementation from C.M when 
   // emitting the following explicit interface implementation, 
   // it is necessary to use a MethodImpl.
   //
   string I.M()
   {
      return "The I.M implementation of C";
   }
}

class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      string name = "DefineMethodOverrideExample";
      AssemblyName asmName = new AssemblyName(name);
      AssemblyBuilder ab =
          AppDomain.CurrentDomain.DefineDynamicAssembly(
              asmName, AssemblyBuilderAccess.Run);
      ModuleBuilder mb = ab.DefineDynamicModule(name);

      TypeBuilder tb =
          mb.DefineType("C", TypeAttributes.Public, typeof(A));
      tb.AddInterfaceImplementation(typeof(I));

      // Build the method body for the explicit interface 
      // implementation. The name used for the method body 
      // can be anything. Here, it is the name of the method,
      // qualified by the interface name.
      //
      MethodBuilder mbIM = tb.DefineMethod("I.M",
          MethodAttributes.Private | MethodAttributes.HideBySig |
              MethodAttributes.NewSlot | MethodAttributes.Virtual |
              MethodAttributes.Final,
          typeof(string),
          Type.EmptyTypes);
      ILGenerator il = mbIM.GetILGenerator();
      il.Emit(OpCodes.Ldstr, "The I.M implementation of C");
      il.Emit(OpCodes.Ret);

      // DefineMethodOverride is used to associate the method 
      // body with the interface method that is being implemented.
      //
      tb.DefineMethodOverride(mbIM, typeof(I).GetMethod("M"));

      MethodBuilder mbM = tb.DefineMethod("M",
          MethodAttributes.Public | MethodAttributes.ReuseSlot |
              MethodAttributes.Virtual | MethodAttributes.HideBySig,
          typeof(string),
          Type.EmptyTypes);
      il = mbM.GetILGenerator();
      il.Emit(OpCodes.Ldstr, "Overriding A.M from C.M");
      il.Emit(OpCodes.Ret);

      Type tc = tb.CreateType();

      Object test = Activator.CreateInstance(tc);

      MethodInfo mi = typeof(I).GetMethod("M");
      outputBlock.Text += mi.Invoke(test, null) + "\n";

      mi = typeof(A).GetMethod("M");
      outputBlock.Text += mi.Invoke(test, null) + "\n";
   }
}

/* This code example produces the following output:

The I.M implementation of C
Overriding A.M from C.M
 */

Version Information

Silverlight

Supported in: 5, 4, 3

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Change History

Date

History

Reason

December 2010

Added a warning that after TypeBuilder is called, you cannot alter some aspects of methodInfoBody.

Customer feedback.