TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) Methode

Definitie

Hiermee geeft u een bepaalde methodetekst op die een bepaalde methodedeclaratie implementeert, mogelijk met een andere naam.

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)

Parameters

methodInfoBody
MethodInfo

De methodebody die moet worden gebruikt. Dit moet een MethodBuilder object zijn.

methodInfoDeclaration
MethodInfo

De methode waarvan de declaratie moet worden gebruikt.

Uitzonderingen

methodInfoBody behoort niet tot deze klasse.

methodInfoBody of methodInfoDeclaration is null.

Het type is eerder gemaakt met behulp van CreateType().

– of –

Het declaratietype methodInfoBody is niet het type dat wordt vertegenwoordigd door dit TypeBuilder.

Voorbeelden

Het volgende codevoorbeeld bevat een interface I met een methode M(), een basisklasse A die de interface implementeert en een afgeleide klasse C die de implementatie van M() de basisklasse overschrijft en ook een afzonderlijke expliciete implementatie van I.M().

De main() methode van het codevoorbeeld laat zien hoe u de afgeleide klasse Cverzendt. Het overschrijven van A.M() wordt bereikt door simpelweg een methode M() met dezelfde handtekening te verzenden. Als u echter een afzonderlijke implementatie wilt I.M()bieden, moet u een methodetekst definiëren en vervolgens de methode gebruiken om die DefineMethodOverride methodebody te koppelen aan een MethodInfo vertegenwoordiging I.M(). De naam van de methodebody maakt niet uit.

In het codevoorbeeld wordt een exemplaar van de verzonden klasse gemaakt. Het verkrijgt een MethodInfo object voor I.M()en gebruikt het om de expliciete interface-implementatie van de verzonden klasse aan te roepen. Vervolgens wordt een MethodInfo object opgehaald voor A.M()en wordt het gebruikt om de onderdrukking van die methode van de verzonden klasse aan te roepen.

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
'

Opmerkingen

Gebruik deze methode niet om methode-onderdrukkingen of interface-implementaties te verzenden. Als u een methode van een basisklasse wilt overschrijven of een methode van een interface wilt implementeren, verzendt u gewoon een methode met dezelfde naam en handtekening als de methode die moet worden overschreven of geïmplementeerd, zoals wordt gedemonstreerd in het codevoorbeeld.

De DefineMethodOverride methode wordt gebruikt wanneer een hoofdtekst van een methode en een methodedeclaratie verschillende namen hebben. Een klasse kan bijvoorbeeld een basisklassemethode overschrijven en ook een afzonderlijke implementatie bieden voor een interfacelid met dezelfde naam, zoals wordt gedemonstreerd in het codevoorbeeld.

DefineMethodOverride definieert een methodimpl, dat bestaat uit een paar metagegevenstokens. Het ene token verwijst naar een implementatie en het andere token verwijst naar een declaratie die door de hoofdtekst wordt geïmplementeerd. De hoofdtekst moet worden gedefinieerd voor het type waarop de methode impl is gedefinieerd en de hoofdtekst moet virtueel zijn (Overridable in Visual Basic). De declaratie kan worden gedaan aan een methode die is gedefinieerd op een interface die is geïmplementeerd door het type, een methode op een afgeleide klasse of een methode die in het type is gedefinieerd. Als de declaratie alleen op een interface staat, wordt de sleuf die voor de interface is gedefinieerd, gewijzigd. Als de declaratie wordt gedaan aan een methode op basistype, wordt de sleuf voor de methode overschreven en worden eventuele duplicaten voor de overschreven methode ook vervangen. De overschreven methode kan niet de werkelijke methode zijn die wordt gedeclareerd. Als de methode zich op hetzelfde type bevindt, wordt de site vervangen en worden eventuele duplicaten voor de vervangen methoden overschreven.

Note

Zie de documentatie over ECMA Partition II Metadata in MethodImpl and Standard ECMA-335 - Common Language Infrastructure (CLI) voor meer informatie over methode-impls.

Important

Nadat de DefineMethodOverride methode is aangeroepen, kunnen sommige functies niet methodInfoBody worden gewijzigd. U kunt bijvoorbeeld geen kenmerk toepassen op een algemene typeparameter van met behulp van methodInfoBody de SetGenericParameterAttributes methode. Als u de DefineMethodOverride methode moet gebruiken, moet u dit doen nadat alle kenmerken zijn methodInfoBody gedefinieerd.

Van toepassing op