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 または methodInfoDeclarationnull

この型は、以前に CreateType() を使用して作成されました。

-または-

methodInfoBodyの宣言型は、このTypeBuilderで表される型ではありません。

次のコード例には、メソッド M()、インターフェイスを実装する基底クラス A、およびM()の基底クラスの実装をオーバーライドし、I.M()の個別の明示的な実装を提供する派生クラス Cを含むインターフェイス Iが含まれています。

コード例の main() メソッドは、派生クラスの Cを出力する方法を示しています。 A.M()のオーバーライドは、同じシグネチャを持つメソッドM()を出力するだけで実現されます。 ただし、I.M()の個別の実装を提供するには、メソッド本体を定義してから、DefineMethodOverride メソッドを使用して、そのメソッド本体をI.M()を表すMethodInfoに関連付ける必要があります。 メソッド本体の名前は関係ありません。

このコード例では、出力されたクラスのインスタンスを作成します。 I.M()MethodInfo オブジェクトを取得し、それを使用して出力されたクラスの明示的なインターフェイス実装を呼び出します。 次に、A.M()MethodInfo オブジェクトを取得し、それを使用してそのメソッドの出力されたクラスのオーバーライドを呼び出します。

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を定義します。 1 つのトークンは実装を指し、もう 1 つのトークンは本体が実装する宣言を指します。 本体は、メソッドimplが定義されている型で定義する必要があり、本体は仮想である必要があります (Overridable Visual Basic)。 宣言は、型によって実装されるインターフェイスで定義されたメソッド、派生クラスのメソッド、または型で定義されたメソッドに対して行うことができます。 宣言がインターフェイスのみに存在する場合、インターフェイスに対して定義されているスロットが変更されます。 基本型のメソッドに対して宣言が行われると、メソッドのスロットがオーバーライドされ、オーバーライドされたメソッドの重複も置き換えられます。 オーバーライドされたメソッドは、宣言されている実際のメソッドにすることはできません。 メソッドが同じ型にある場合は、スロットが置き換えられ、置き換えられたメソッドの重複がオーバーライドされます。

Note

メソッドの実装の詳細については、ECMA C# と共通言語インフラストラクチャ標準および標準 ECMA-335 - 共通言語インフラストラクチャ (CLI) の ECMA Partition II Metadata ドキュメントのMethodImplを参照してください。

Important

DefineMethodOverride メソッドを呼び出した後、methodInfoBodyの一部の機能を変更することはできません。 たとえば、SetGenericParameterAttributes メソッドを使用して、methodInfoBodyのジェネリック型パラメーターに属性を適用することはできません。 DefineMethodOverrideメソッドを使用する必要がある場合は、methodInfoBodyのすべての特性が定義された後で行います。

適用対象