TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) 方法

定義

指定實作給定方法宣告的給定方法主體,可能會使用其他名稱。

C#
public void DefineMethodOverride(System.Reflection.MethodInfo methodInfoBody, System.Reflection.MethodInfo methodInfoDeclaration);

參數

methodInfoBody
MethodInfo

要使用的方法主體。 應該是 MethodBuilder 物件。

methodInfoDeclaration
MethodInfo

要使用其宣告的方法。

例外狀況

methodInfoBody 不屬於這個類別。

methodInfoBodymethodInfoDeclarationnull

先前使用 CreateType() 建立的類型。

-或-

methodInfoBody 的宣告類型不是 TypeBuilder 所表示的類型。

範例

下列程式代碼範例包含具有 方法的介面I、實作 介面的基類A,以及覆寫 之基類實作的衍生類別C,也提供 個別的明確實M()I.M()M()

程式 main() 代碼範例的 方法示範如何發出衍生類別 C。 的 A.M() 覆寫只是藉由發出具有相同簽章的方法 M() 來完成。 不過,若要提供的個別實作 I.M(),您必須定義方法主體,然後使用 DefineMethodOverride 方法將該方法主體與 MethodInfo 表示 的 I.M()產生關聯。 方法主體的名稱並不重要。

程式代碼範例會建立發出類別的實例。 它會取得 MethodInfoI.M()物件,並用它來叫用所發出類別的明確介面實作。 然後,它會取得 MethodInfoA.M()物件,並用它來叫用發出之類別的該方法覆寫。

C#
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 =
            AppDomain.CurrentDomain.DefineDynamicAssembly(
                asmName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");

        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();

        // Save the emitted assembly, to examine with Ildasm.exe.
        ab.Save(name + ".dll");

        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
 */

備註

請勿使用此方法發出方法覆寫或介面實作。 若要覆寫基類的方法,或實作介面的方法,只要發出與要覆寫或實作方法相同名稱和簽章的方法,如程式代碼範例所示。

當方法主體和方法宣告具有不同的名稱時,就會 DefineMethodOverride 使用 方法。 例如,類別可能會覆寫基類方法,同時也為具有相同名稱的介面成員提供個別的實作,如程式代碼範例所示。

DefineMethodOverride 會定義 , methodimpl其中包含一對元數據令牌。 一個令牌指向實作,另一個令牌指向主體所實作的宣告。 本文必須定義於方法 impl 所定義的類型上,而且本文必須是 Visual Basic) 中的虛擬 (Overridable 。 宣告可以設定為型別所實作之介面上定義的方法、衍生類別上的方法,或型別中定義的方法。 如果宣告只位於介面上,則會改變為介面定義的位置。 如果宣告是在基底類型上對方法進行,則會覆寫方法的位置,而且也會取代覆寫方法的任何重複專案。 覆寫的方法不能是宣告的實際方法。 如果方法位於相同類型上,則會取代位置,並覆寫已取代方法的任何重複專案。

注意

如需方法實作的詳細資訊,請參閱 MethodImpl ECMA 分割區 II 元數據檔中的 ECMA C# 和 Common Language Infrastructure Standard and Standard ECMA-335 - Common Language Infrastructure (CLI)

重要

DefineMethodOverride呼叫 方法之後,就無法變更 的某些methodInfoBody功能。 例如,您無法使用 SetGenericParameterAttributes 方法,將屬性套用至 的methodInfoBody泛型型別參數。 如果您必須使用 DefineMethodOverride 方法,請在 已定義 的所有特性 methodInfoBody 之後執行此動作。

適用於

產品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1