Export (0) Print
Expand All

TypeBuilder.DefineMethodOverride Method

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)

public void DefineMethodOverride(
	MethodInfo methodInfoBody,
	MethodInfo methodInfoDeclaration
)

Parameters

methodInfoBody
Type: System.Reflection.MethodInfo

The method body to be used. This should be a MethodBuilder object.

methodInfoDeclaration
Type: System.Reflection.MethodInfo

The method whose declaration is to be used.

ExceptionCondition
ArgumentException

methodInfoBody does not belong to this class.

ArgumentNullException

methodInfoBody or methodInfoDeclaration is null.

InvalidOperationException

The type was previously created using CreateType.

-or-

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

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

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.

The following code 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.

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

public interface I 
{
    void M();
}

public class A 
{
    public virtual void M() { Console.WriteLine("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 void M() 
    { 
        Console.WriteLine("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. 
    // 
    void I.M() 
    {
        Console.WriteLine("The I.M implementation of C"); 
    }
}

class Test 
{
    static void Main() 
    {
        string name = "DefineMethodOverrideExample";
        AssemblyName asmName = new AssemblyName(name);
        AssemblyBuilder ab = 
            AppDomain.CurrentDomain.DefineDynamicAssembly(
                asmName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");

        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,
            null,
            Type.EmptyTypes);
        ILGenerator il = mbIM.GetILGenerator();
        il.Emit(OpCodes.Ldstr, "The I.M implementation of C");
        il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", 
            new Type[] { typeof(string) }));
        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, 
            null, 
            Type.EmptyTypes);
        il = mbM.GetILGenerator();
        il.Emit(OpCodes.Ldstr, "Overriding A.M from C.M");
        il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", 
            new Type[] { typeof(string) }));
        il.Emit(OpCodes.Ret);

        Type tc = tb.CreateType();

        // Save the emitted assembly, to examine with Ildasm.exe.
        ab.Save(name + ".dll");

        Object test = Activator.CreateInstance(tc);

        MethodInfo mi = typeof(I).GetMethod("M");
        mi.Invoke(test, null);

        mi = typeof(A).GetMethod("M");
        mi.Invoke(test, null);
    }
}

/* This code example produces the following output:

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

.NET Framework

Supported in: 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Show:
© 2014 Microsoft