TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) Methode

Definition

Gibt einen bestimmten Methodentext an, der eine bestimmte Methodendeklaration implementiert, möglicherweise mit einem anderen Namen.

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)

Parameter

methodInfoBody
MethodInfo

Der zu verwendende Methodentext. Dies sollte ein MethodBuilder Objekt sein.

methodInfoDeclaration
MethodInfo

Die Methode, deren Deklaration verwendet werden soll.

Ausnahmen

methodInfoBody gehört nicht zu dieser Klasse.

methodInfoBody oder methodInfoDeclaration ist null.

Der Typ wurde zuvor mit CreateType().

-oder-

Der deklarierende Typ von methodInfoBody ist nicht der Typ, der durch diesen TypeBuilderdargestellt wird.

Beispiele

Das folgende Codebeispiel enthält eine Schnittstelle I mit einer Methode M(), einer Basisklasse A , die die Schnittstelle implementiert, und eine abgeleitete Klasse C , die die Basisklassenimplementierung M() außer Kraft setzt und außerdem eine separate explizite Implementierung von I.M().

Die main() Methode des Codebeispiels zeigt, wie die abgeleitete Klasse Causgegeben wird. Die Außerkraftsetzung A.M() erfolgt einfach durch Das Ausstrahlen einer Methode M() mit derselben Signatur. Um jedoch eine separate Implementierung bereitzustellen I.M(), müssen Sie einen Methodentext definieren und dann die Methode verwenden, um diesen DefineMethodOverride Methodentext einer MethodInfo Darstellung I.M()zuzuordnen. Der Name des Methodentexts spielt keine Rolle.

Im Codebeispiel wird eine Instanz der ausgegebenen Klasse erstellt. Es ruft ein MethodInfo Objekt für I.M()und verwendet es, um die explizite Schnittstellenimplementierung der ausgegebenen Klasse aufzurufen. Anschließend wird ein MethodInfo Objekt für A.M()und verwendet es, um die Außerkraftsetzung dieser Methode aufzurufen.

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 =
            AssemblyBuilder.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,
            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();

        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 = _
            AssemblyBuilder.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, _
            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()
        
        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
'

Hinweise

Verwenden Sie diese Methode nicht, um Methodenüberschreibungen oder Schnittstellenimplementierungen auszugeben. Um eine Methode einer Basisklasse außer Kraft zu setzen oder eine Methode einer Schnittstelle zu implementieren, geben Sie einfach eine Methode mit demselben Namen und derselben Signatur wie die Methode aus, die überschrieben oder implementiert werden soll, wie im Codebeispiel veranschaulicht.

Die DefineMethodOverride Methode wird verwendet, wenn ein Methodentext und eine Methodendeklaration unterschiedliche Namen haben. Eine Klasse kann z. B. eine Basisklassenmethode außer Kraft setzen und auch eine separate Implementierung für ein Schnittstellenelement mit demselben Namen bereitstellen, wie im Codebeispiel gezeigt.

DefineMethodOverride definiert ein methodimpl, das aus einem Paar von Metadatentoken besteht. Ein Token verweist auf eine Implementierung, und das andere Token verweist auf eine Deklaration, die der Textkörper implementiert. Der Text muss für den Typ definiert werden, für den die Methodeimpl definiert ist, und der Textkörper muss virtuell sein (Overridable in Visual Basic). Die Deklaration kann an einer Methode erfolgen, die auf einer Schnittstelle definiert ist, die vom Typ implementiert wird, eine Methode für eine abgeleitete Klasse oder eine im Typ definierte Methode. Wenn sich die Deklaration nur auf einer Schnittstelle befindet, wird der für die Schnittstelle definierte Steckplatz geändert. Wenn die Deklaration an einer Methode für einen Basistyp vorgenommen wird, wird der Steckplatz für die Methode überschrieben, und alle Duplikate für die überschriebene Methode werden ebenfalls ersetzt. Die überschriebene Methode kann nicht die tatsächliche Methode sein, die deklariert wird. Wenn sich die Methode auf demselben Typ befindet, wird der Steckplatz ersetzt, und alle Duplikate für die ersetzten Methoden werden überschrieben.

Note

Weitere Informationen zu Methodenimpls finden Sie MethodImpl in der ECMA Partition II-Metadatendokumentation unter ECMA C# und Common Language Infrastructure Standards und Standard ECMA-335 - Common Language Infrastructure (CLI).

Important

Nachdem die DefineMethodOverride Methode aufgerufen wurde, können einige Features methodInfoBody nicht mehr geändert werden. Sie können z. B. kein Attribut auf einen generischen Typparameter methodInfoBody mithilfe der SetGenericParameterAttributes Methode anwenden. Wenn Sie die DefineMethodOverride Methode verwenden müssen, müssen Sie dies tun, nachdem alle Merkmale methodInfoBody definiert wurden.

Gilt für: