TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) Method

定义

指定实现给定方法声明的给定方法体(可能使用其他名称)。Specifies a given method body that implements a given method declaration, potentially with a different name.

public:
 void DefineMethodOverride(System::Reflection::MethodInfo ^ methodInfoBody, System::Reflection::MethodInfo ^ methodInfoDeclaration);
public void DefineMethodOverride (System.Reflection.MethodInfo methodInfoBody, System.Reflection.MethodInfo methodInfoDeclaration);
member this.DefineMethodOverride : System.Reflection.MethodInfo * System.Reflection.MethodInfo -> unit
Public Sub DefineMethodOverride (methodInfoBody As MethodInfo, methodInfoDeclaration As MethodInfo)

参数

methodInfoBody
MethodInfo MethodInfo MethodInfo MethodInfo

要使用的方法体。The method body to be used. 应当为 MethodBuilder 对象。This should be a MethodBuilder object.

methodInfoDeclaration
MethodInfo MethodInfo MethodInfo MethodInfo

要使用其声明的方法。The method whose declaration is to be used.

异常

methodInfoBody 不属于此类。methodInfoBody does not belong to this class.

methodInfoBodymethodInfoDeclarationnullmethodInfoBody or methodInfoDeclaration is null.

该类型是以前使用 CreateType() 创建的。The type was previously created using CreateType().

- 或 --or- methodInfoBody 的声明类型不是此 TypeBuilder 表示的类型。The declaring type of methodInfoBody is not the type represented by this TypeBuilder.

示例

下面的代码示例包含一个接口I ,该接口M()具有一个方法、 A一个实现接口的基类和一个派生M()C ,该派生类将重写的基类实现,并且还提供的I.M()单独显式实现。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().

此代码示例的C方法演示如何发出派生类。main()The main() method of the code example shows how to emit the derived class C. 仅通过发出A.M()一个具有相同签名的方法M()即可实现的重写。The override of A.M() is accomplished simply by emitting a method M() with the same signature. 但是,若I.M()要提供的单独实现,你必须定义一个方法体,然后DefineMethodOverride使用方法将MethodInfo该方法主体与表示I.M()进行关联。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. 它获取MethodInfoI.M()对象,并使用它来调用发出的类的显式接口实现。It obtains a MethodInfo object for I.M(), and uses it to invoke the emitted class's explicit interface implementation. 然后A.M(),它获取MethodInfo的对象,并使用它来调用该方法的已发出类的重写。It then obtains a MethodInfo object for A.M(), and uses it to invoke the emitted class's override of that method.

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

public interface class I 
{
    void M();
};

public ref 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 ref class C : A, I 
{
public:
    virtual void M() override 
    { 
        Console::WriteLine("Overriding A.M from C.M"); 
    }

private:
    // In order to provide a different implementation from C.M when 
    // emitting the following explicit interface implementation, 
    // it is necessary to use a MethodImpl.
    //
    virtual void IM() sealed = I::M 
    {
        Console::WriteLine("The I::M implementation of C");
    }
};

void main() 
{
    String^ name = "DefineMethodOverrideExample";
    AssemblyName^ asmName = gcnew AssemblyName(name);
    AssemblyBuilder^ ab = 
        AppDomain::CurrentDomain->DefineDynamicAssembly(
            asmName, AssemblyBuilderAccess::RunAndSave);
    ModuleBuilder^ mb = ab->DefineDynamicModule(name, name + ".dll");

    TypeBuilder^ tb = 
        mb->DefineType("C", TypeAttributes::Public, A::typeid);
    tb->AddInterfaceImplementation(I::typeid);

    // 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,
        nullptr,
        Type::EmptyTypes);
    ILGenerator^ il = mbIM->GetILGenerator();
    il->Emit(OpCodes::Ldstr, "The I.M implementation of C");
    il->Emit(OpCodes::Call, Console::typeid->GetMethod("WriteLine", 
        gcnew array<Type^> { String::typeid }));
    il->Emit(OpCodes::Ret);

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

    MethodBuilder^ mbM = tb->DefineMethod("M", 
        MethodAttributes::Public | MethodAttributes::ReuseSlot | 
            MethodAttributes::Virtual | MethodAttributes::HideBySig, 
        nullptr, 
        Type::EmptyTypes);
    il = mbM->GetILGenerator();
    il->Emit(OpCodes::Ldstr, "Overriding A.M from C.M");
    il->Emit(OpCodes::Call, Console::typeid->GetMethod("WriteLine", 
        gcnew array<Type^> { String::typeid }));
    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 = I::typeid->GetMethod("M");
    mi->Invoke(test, nullptr);

    mi = A::typeid->GetMethod("M");
    mi->Invoke(test, nullptr);
}

/* 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 
{
    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
 */
Imports System.Reflection
Imports System.Reflection.Emit

Public Interface I
    Sub M() 
End Interface

Public Class A
    Public Overridable Sub M() 
        Console.WriteLine("In method A.M")
    End Sub
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 Sub M() 
        Console.WriteLine("Overriding A.M from C.M")
    End Sub
    
    ' 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 Sub IM() Implements I.M
        Console.WriteLine("The I.M implementation of C")
    End Sub
End Class

Class Test
    
    Shared Sub Main() 

        Dim name As String = "DefineMethodOverrideExample"
        Dim asmName As New AssemblyName(name)
        Dim ab As AssemblyBuilder = _
            AppDomain.CurrentDomain.DefineDynamicAssembly( _
                asmName, AssemblyBuilderAccess.RunAndSave)
        Dim mb As ModuleBuilder = _
            ab.DefineDynamicModule(name, name & ".dll")
        
        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, _
            Nothing, _
            Type.EmptyTypes)
        Dim il As ILGenerator = mbIM.GetILGenerator()
        il.Emit(OpCodes.Ldstr, "The I.M implementation of C")
        il.Emit(OpCodes.Call, GetType(Console).GetMethod("WriteLine", _
            New Type() {GetType(String)}))
        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, _
            Nothing, _
            Type.EmptyTypes)
        il = mbM.GetILGenerator()
        il.Emit(OpCodes.Ldstr, "Overriding A.M from C.M")
        il.Emit(OpCodes.Call, GetType(Console).GetMethod("WriteLine", _
            New Type() {GetType(String)}))
        il.Emit(OpCodes.Ret)
        
        Dim tc As Type = tb.CreateType()
        
        ' Save the emitted assembly, to examine with Ildasm.exe.
        ab.Save(name & ".dll")
        
        Dim test As Object = Activator.CreateInstance(tc)
        
        Dim mi As MethodInfo = GetType(I).GetMethod("M")
        mi.Invoke(test, Nothing)
        
        mi = GetType(A).GetMethod("M")
        mi.Invoke(test, Nothing)
    
    End Sub
End Class

' This code example produces the following output:
'
'The I.M implementation of C
'Overriding A.M from C.M
' 

注解

不要使用此方法发出方法重写或接口实现。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.

DefineMethodOverride方法体和方法声明具有不同的名称时,使用方法。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定义一个methodimpl,它包含一对元数据标记。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. 主体必须在 impl 定义的类型上定义,并且正文必须是虚拟的(Overridable在 Visual Basic 中)。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.

备注

有关方法 impls 的详细信息,请MethodImpl参阅 ECMA Partition II 元数据文档中的。For more information about method impls, see MethodImpl in the ECMA Partition II Metadata documentation. 可联机获取该文档;请参阅 MSDN 上的 ECMA C# 和公共语言基础结构标准和 Ecma International 网站上的标准 ECMA-335 - 公共语言基础结构 (CLI)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.

重要

调用方法后,的methodInfoBody某些功能将无法更改。 DefineMethodOverrideAfter the DefineMethodOverride method is called, some features of methodInfoBody cannot be changed. 例如,不能通过methodInfoBody SetGenericParameterAttributes使用方法将特性应用于的泛型类型参数。For example, you cannot apply an attribute to a generic type parameter of methodInfoBody by using the SetGenericParameterAttributes method. 如果必须使用DefineMethodOverride方法,请在定义所有methodInfoBody特征后执行此操作。If you must use the DefineMethodOverride method, do so after all characteristics of methodInfoBody have been defined.

适用于