TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) Método
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Especifica um dado corpo de método que implementa uma determinada declaração de método, potencialmente com um nome diferente.
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)
Parâmetros
- methodInfoBody
- MethodInfo
O método do corpo a ser utilizado. Isto deve ser um MethodBuilder objeto.
- methodInfoDeclaration
- MethodInfo
O método cuja declaração deve ser utilizada.
Exceções
methodInfoBody não pertence a esta classe.
methodInfoBody ou methodInfoDeclaration é null.
O tipo foi anteriormente criado usando CreateType().
-ou-
O tipo declarante de methodInfoBody não é o tipo representado por este TypeBuilder.
Exemplos
O exemplo de código seguinte contém uma interface I com um método M(), uma classe A base que implementa a interface, e uma classe C derivada que sobrepõe a implementação da classe base de M() e também fornece uma implementação explícita separada de I.M().
O main() método do exemplo de código mostra como emitir a classe Cderivada . A sobreposição de A.M() é conseguida simplesmente emitindo um método M() com a mesma assinatura. No entanto, para fornecer uma implementação separada de I.M(), deve definir um corpo de método e depois usar o DefineMethodOverride método para associar esse corpo de método a um MethodInfo que representa I.M(). O nome do corpo do método não importa.
O exemplo de código cria uma instância da classe emitida. Obtém um MethodInfo objeto para I.M(), e usa-o para invocar a implementação explícita da interface da classe emitida. Depois, obtém um MethodInfo objeto para A.M(), e usa-o para invocar a substituição desse método pela classe emitida.
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
'
Observações
Não utilize este método para emitir sobreposições de método ou implementações de interface. Para substituir um método de uma classe base ou implementar um método de interface, basta emitir um método com o mesmo nome e assinatura do método a ser sobreposto ou implementado, como demonstrado no exemplo do código.
O DefineMethodOverride método é usado quando um corpo de método e uma declaração de método têm nomes diferentes. Por exemplo, uma classe pode sobrescrever um método de classe base e também fornecer uma implementação separada para um membro de interface com o mesmo nome, como demonstrado no exemplo de código.
DefineMethodOverride define um methodimpl, que consiste num par de tokens de metadados. Um token aponta para uma implementação, e o outro para uma declaração que o organismo implementa. O corpo deve ser definido no tipo em que o método está definido, e o corpo deve ser virtual (Overridable em Visual Basic). A declaração pode ser feita a um método definido numa interface implementada pelo tipo, a um método numa classe derivada, ou a um método definido no tipo. Se a declaração for apenas numa interface, o slot definido para a interface é alterado. Se a declaração for feita a um método num tipo base, o slot para o método é sobreposto e quaisquer duplicados para o método sobreposto também são substituídos. O método sobreposto não pode ser o método que é declarado. Se o método for do mesmo tipo, o slot é substituído e quaisquer duplicados dos métodos substituídos são sobrepostos.
Note
Para mais informações sobre os métodos implicados, consulte MethodImpl a documentação de Metadados ECMA Partition II em ECMA C# e Common Language Infrastructure Standards e Standard ECMA-335 - Common Language Infrastructure (CLI).
Importante
Depois de o DefineMethodOverride método ser chamado, algumas características de methodInfoBody não podem ser alteradas. Por exemplo, não pode aplicar um atributo a um parâmetro genérico de methodInfoBody usando o SetGenericParameterAttributes método. Se tiver de usar o DefineMethodOverride método, faça-o depois de todas as características de methodInfoBody terem sido definidas.