語言

TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) 方法

定義

指定一個方法體,實作特定方法宣告,可能名稱不同。

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。

該類型先前是使用 CreateType()。

-或-

宣告的 methodInfoBody 類型並非由此 TypeBuilder類型所代表的類型。

範例

以下程式碼範例包含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 都定義完畢後使用。

適用於