TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
指定一個方法體,實作特定方法宣告,可能名稱不同。
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
將使用的方法本體。 這應該是一個 MethodBuilder 物件。
- methodInfoDeclaration
- MethodInfo
所宣告的方法。
例外狀況
methodInfoBody 不屬於此類別。
methodInfoBody 或 methodInfoDeclaration 為 null。
範例
以下程式碼範例包含I一個介面,包含一個方法M()、一個實作該介面的基底類別A,以及一個覆蓋基C底類別實作的導出類別M(),並且提供獨立的明確實作。I.M()
main()程式碼範例中的方法展示了如何發射導出類別 C。 覆寫 的 A.M() 方法是直接輸出具有相同簽名的方法 M() 。 然而,若要提供獨立的實作, I.M()你必須定義一個方法實體,然後用該 DefineMethodOverride 方法將該方法 MethodInfo 實體與表示 I.M()的 關聯起來。 方法體的名稱並不重要。
程式碼範例建立出已發射類別的實例。 它取得 MethodInfo 一個物件, I.M()並用它來呼叫所發射類別的明確介面實作。 接著取得 MethodInfo 一個物件, A.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 =
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
'
備註
請勿使用此方法來執行方法覆寫或介面實作。 若要覆寫基底類別的方法或實作介面的方法,只需發出與待覆寫或實作方法名稱與簽名相同的方法,如程式碼範例所示。
DefineMethodOverride當方法主體與方法宣告名稱不同時,會使用此方法。 例如,一個類別可能會覆蓋基底類別的方法,並為同名的介面成員提供獨立實作,如程式碼範例所示。
DefineMethodOverride 定義了一個 methodimpl,由一對元資料標記組成。 一個標記指向實作,另一個標記指向主體實作的宣告。 實體必須定義在方法impl所定義的類型上,且實體必須是虛擬的(Overridable在Visual Basic中)。 宣告可以對由該型別實作的介面上定義的方法、派生類別上的方法,或是該型別中定義的方法進行。 若宣告僅在介面上,則該介面定義的槽位會被更改。 若宣告為基底型別上的方法,該方法的插槽會被覆寫,且該方法的重複欄位也會被替換。 覆寫的方法不能是實際宣告的方法。 若方法屬於同一類型,則該槽位會被替換,且所有重複的重複方法會被覆寫。
Note
欲了解更多方法實例的資訊,請參閱 MethodImpl ECMA 分割區 II 元資料文件中的 ECMA C# 與通用語言基礎架構標準 及 標準 ECMA-335 - 通用語言基礎架構(CLI)相關資料。
Important
在方法被呼叫後 DefineMethodOverride ,某些 methodInfoBody 特徵無法更改。 例如,你無法透過使用該methodInfoBody方法對一般型別參數SetGenericParameterAttributes套用屬性。 如果必須使用此 DefineMethodOverride 方法,請在所有特徵 methodInfoBody 都定義完畢後使用。