TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) Metod
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Anger en viss metodtext som implementerar en viss metoddeklaration, eventuellt med ett annat namn.
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)
Parametrar
- methodInfoBody
- MethodInfo
Metodtexten som ska användas. Detta bör vara ett MethodBuilder objekt.
- methodInfoDeclaration
- MethodInfo
Den metod vars deklaration ska användas.
Undantag
methodInfoBody tillhör inte den här klassen.
methodInfoBody eller methodInfoDeclaration är null.
Typen skapades tidigare med .CreateType()
-eller-
Deklareringstypen methodInfoBody är inte den typ som representeras av den här TypeBuilder.
Exempel
Följande kodexempel innehåller ett gränssnitt I med en metod M(), en basklass A som implementerar gränssnittet och en härledd klass C som åsidosätter basklassimplementeringen av M() och även ger en separat explicit implementering av I.M().
Metoden main() i kodexemplet visar hur du genererar den härledda klassen C. Åsidosättningen av A.M() åsidosätts helt enkelt genom att en metod M() med samma signatur genereras. Men för att tillhandahålla en separat implementering av I.M()måste du definiera en metodtext och sedan använda metoden för att associera metodtexten DefineMethodOverride med en MethodInfo som representerar I.M(). Namnet på metodtexten spelar ingen roll.
Kodexemplet skapar en instans av den avgivna klassen. Det hämtar ett MethodInfo -objekt för I.M()och använder det för att anropa den avgivna klassens explicita gränssnittsimplementering. Det hämtar sedan ett MethodInfo objekt för A.M()och använder det för att anropa den avgivna klassens åsidosättning av den metoden.
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
'
Kommentarer
Använd inte den här metoden för att generera metodidosättningar eller gränssnittsimplementeringar. Om du vill åsidosätta en metod för en basklass eller implementera en metod för ett gränssnitt genererar du helt enkelt en metod med samma namn och signatur som den metod som ska åsidosättas eller implementeras, vilket visas i kodexemplet.
Metoden DefineMethodOverride används när en metodtext och en metoddeklaration har olika namn. En klass kan till exempel åsidosätta en basklassmetod och även tillhandahålla en separat implementering för en gränssnittsmedlem med samma namn, vilket visas i kodexemplet.
DefineMethodOverride definierar en methodimpl, som består av ett par metadatatoken. En token pekar på en implementering och den andra token pekar på en deklaration som brödtexten implementerar. Brödtexten måste definieras på den typ som metoden impl definieras på och brödtexten måste vara virtuell (Overridable i Visual Basic). Deklarationen kan göras till en metod som definierats i ett gränssnitt som implementerats av typen, en metod för en härledd klass eller en metod som definierats i typen. Om deklarationen endast finns i ett gränssnitt ändras det fack som definierats för gränssnittet. Om deklarationen görs till en metod av bastyp åsidosätts platsen för metoden och eventuella dubbletter för den åsidosatta metoden ersätts också. Den åsidosatta metoden kan inte vara den faktiska metod som deklareras. Om metoden är av samma typ ersätts facket och eventuella dubbletter för de ersatta metoderna åsidosätts.
Note
Mer information om metodimplser MethodImpl finns i dokumentationen om ECMA Partition II-metadata på ECMA C# och Common Language Infrastructure Standards och Standard ECMA-335 – Common Language Infrastructure (CLI).
Important
DefineMethodOverride När metoden har anropats kan vissa funktioner methodInfoBody i inte ändras. Du kan till exempel inte använda ett attribut för en generisk typparameter methodInfoBody för med hjälp SetGenericParameterAttributes av metoden. Om du måste använda DefineMethodOverride metoden gör du det när alla egenskaper methodInfoBody för har definierats.