TypeBuilder.DefineMethodOverride(MethodInfo, MethodInfo) メソッド

定義

特定のメソッド宣言 (名前が異なる可能性があります) を実装する特定のメソッド本体を指定します。Specifies a given method body that implements a given method declaration, potentially with a different name.

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

使用するメソッド本体。The method body to be used. これは MethodBuilder オブジェクトである必要があります。This should be a MethodBuilder object.

methodInfoDeclaration
MethodInfo

宣言が使用されるメソッド。The method whose declaration is to be used.

例外

methodInfoBody はこのクラスに属していません。methodInfoBody does not belong to this class.

methodInfoBody または methodInfoDeclarationnull です。methodInfoBody or methodInfoDeclaration is null.

型は CreateType() を使用して既に作成されました。The type was previously created using CreateType().

- または --or- methodInfoBody の宣言型は、この TypeBuilder によって表される型ではありません。The declaring type of methodInfoBody is not the type represented by this TypeBuilder.

次のコード例には、メソッド M()、インターフェイスを実装する基本クラス A、派生 @no__t クラス、および @no__t の基底クラスの実装をオーバーライドし、別の明示的な @no__t を持つインターフェイスが含まれています。I.M() の実装。The following code example contains an interface I with a method M(), a base class A that implements the interface, and a derived class C that overrides the base class implementation of M() and also provides a separate explicit implementation of I.M().

コード例の main() メソッドは、派生クラス C を出力する方法を示しています。The main() method of the code example shows how to emit the derived class C. @No__t-0 のオーバーライドは、同じシグネチャを持つメソッド M() を出力するだけで完了します。The override of A.M() is accomplished simply by emitting a method M() with the same signature. ただし、I.M() の個別の実装を提供するには、メソッド本体を定義し、DefineMethodOverride メソッドを使用して、そのメソッド本体を @no__t を表す @no__t 2 に関連付ける必要があります。However, to provide a separate implementation of I.M(), you must define a method body and then use the DefineMethodOverride method to associate that method body with a MethodInfo representing I.M(). メソッド本体の名前は関係ありません。The name of the method body does not matter.

このコード例では、生成されたクラスのインスタンスを作成します。The code example creates an instance of the emitted class. @No__t-1 の @no__t 0 オブジェクトを取得し、それを使用して、生成されたクラスの明示的なインターフェイスの実装を呼び出します。It obtains a MethodInfo object for I.M(), and uses it to invoke the emitted class's explicit interface implementation. 次に、A.M() の @no__t 0 オブジェクトを取得し、それを使用して、生成されたクラスのメソッドのオーバーライドを呼び出します。It then obtains a MethodInfo object for A.M(), and uses it to invoke the emitted class's override of that method.

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

public interface class I 
{
    void M();
};

public ref 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 ref class C : A, I 
{
public:
    virtual void M() override 
    { 
        Console::WriteLine("Overriding A.M from C.M"); 
    }

private:
    // In order to provide a different implementation from C.M when 
    // emitting the following explicit interface implementation, 
    // it is necessary to use a MethodImpl.
    //
    virtual void IM() sealed = I::M 
    {
        Console::WriteLine("The I::M implementation of C");
    }
};

void main() 
{
    String^ name = "DefineMethodOverrideExample";
    AssemblyName^ asmName = gcnew AssemblyName(name);
    AssemblyBuilder^ ab = 
        AppDomain::CurrentDomain->DefineDynamicAssembly(
            asmName, AssemblyBuilderAccess::RunAndSave);
    ModuleBuilder^ mb = ab->DefineDynamicModule(name, name + ".dll");

    TypeBuilder^ tb = 
        mb->DefineType("C", TypeAttributes::Public, A::typeid);
    tb->AddInterfaceImplementation(I::typeid);

    // 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,
        nullptr,
        Type::EmptyTypes);
    ILGenerator^ il = mbIM->GetILGenerator();
    il->Emit(OpCodes::Ldstr, "The I.M implementation of C");
    il->Emit(OpCodes::Call, Console::typeid->GetMethod("WriteLine", 
        gcnew array<Type^> { String::typeid }));
    il->Emit(OpCodes::Ret);

    // DefineMethodOverride is used to associate the method 
    // body with the interface method that is being implemented.
    //
    tb->DefineMethodOverride(mbIM, I::typeid->GetMethod("M"));

    MethodBuilder^ mbM = tb->DefineMethod("M", 
        MethodAttributes::Public | MethodAttributes::ReuseSlot | 
            MethodAttributes::Virtual | MethodAttributes::HideBySig, 
        nullptr, 
        Type::EmptyTypes);
    il = mbM->GetILGenerator();
    il->Emit(OpCodes::Ldstr, "Overriding A.M from C.M");
    il->Emit(OpCodes::Call, Console::typeid->GetMethod("WriteLine", 
        gcnew array<Type^> { String::typeid }));
    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 = I::typeid->GetMethod("M");
    mi->Invoke(test, nullptr);

    mi = A::typeid->GetMethod("M");
    mi->Invoke(test, nullptr);
}

/* This code example produces the following output:

The I.M implementation of C
Overriding A.M from C.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 = 
            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
 */
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 = _
            AppDomain.CurrentDomain.DefineDynamicAssembly( _
                asmName, AssemblyBuilderAccess.RunAndSave)
        Dim mb As ModuleBuilder = _
            ab.DefineDynamicModule(name, name & ".dll")
        
        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()
        
        ' Save the emitted assembly, to examine with Ildasm.exe.
        ab.Save(name & ".dll")
        
        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
' 

注釈

メソッドのオーバーライドやインターフェイスの実装を出力する場合は、このメソッドを使用しないでください。Do not use this method to emit method overrides or interface implementations. 基底クラスのメソッドをオーバーライドするか、インターフェイスのメソッドを実装するには、コード例に示すように、オーバーライドまたは実装するメソッドと同じ名前およびシグネチャを持つメソッドを生成するだけです。To override a method of a base class or to implement a method of an interface, simply emit a method with the same name and signature as the method to be overridden or implemented, as demonstrated in the code example.

@No__t-0 メソッドは、メソッドの本体とメソッドの宣言の名前が異なる場合に使用されます。The DefineMethodOverride method is used when a method body and a method declaration have different names. たとえば、クラスは、基底クラスのメソッドをオーバーライドし、同じ名前のインターフェイスメンバーに対して個別の実装を提供することがあります。コード例を次に示します。For example, a class might override a base class method and also provide a separate implementation for an interface member with the same name, as demonstrated in the code example.

DefineMethodOverride は、1組のメタデータトークンで構成される methodimpl を定義します。DefineMethodOverride defines a methodimpl, which consists of a pair of metadata tokens. 1つのトークンが実装を指し、もう一方のトークンは本体が実装する宣言を指します。One token points to an implementation, and the other token points to a declaration that the body implements. ボディは、メソッド impl が定義されている型で定義されている必要があります。また、本体は virtual (Visual Basic では @no__t 0) である必要があります。The body must be defined on the type the method impl is defined on, and the body must be virtual (Overridable in Visual Basic). 宣言は、型、派生クラスのメソッド、または型で定義されたメソッドによって実装されたインターフェイスに定義されたメソッドに対して行うことができます。The declaration can be made to a method defined on an interface implemented by the type, a method on a derived class, or a method defined in the type. 宣言がインターフェイスにのみ存在する場合は、インターフェイスに対して定義されているスロットが変更されます。If the declaration is on an interface only, the slot defined for the interface is altered. 宣言が基本型のメソッドに対して行われた場合、メソッドのスロットがオーバーライドされ、オーバーライドされたメソッドのすべての重複も置き換えられます。If the declaration is made to a method on a base type, the slot for the method is overridden and any duplicates for the overridden method are also replaced. オーバーライドされたメソッドを、宣言されている実際のメソッドにすることはできません。The overridden method cannot be the actual method that is declared. メソッドが同じ型にある場合、スロットが置き換えられ、置き換えられたメソッドの重複が上書きされます。If the method is on the same type, the slot is replaced and any duplicates for the replaced methods are overridden.

注意

メソッド impls はの詳細については、ECMA Partition II メタデータドキュメントの「MethodImpl」を参照してください。For more information about method impls, see MethodImpl in the ECMA Partition II Metadata documentation. ドキュメントはオンラインで入手できます。MSDN の「ECMA C# and Common Language Infrastructure Standards」 (ECMA の C# および共通言語基盤の標準規格) と、ECMA のインターナショナル Web サイトにある「Standard ECMA-335 - Common Language Infrastructure (CLI)」を参照してください。The documentation is available online; see ECMA C# and Common Language Infrastructure Standards on MSDN and Standard ECMA-335 - Common Language Infrastructure (CLI) on the Ecma International Web site.

重要

@No__t-0 メソッドが呼び出された後、methodInfoBody の一部の機能を変更できません。After the DefineMethodOverride method is called, some features of methodInfoBody cannot be changed. たとえば、SetGenericParameterAttributes メソッドを使用して methodInfoBody のジェネリック型パラメーターに属性を適用することはできません。For example, you cannot apply an attribute to a generic type parameter of methodInfoBody by using the SetGenericParameterAttributes method. @No__t-0 メソッドを使用する必要がある場合は、methodInfoBody のすべての特性が定義された後に実行します。If you must use the DefineMethodOverride method, do so after all characteristics of methodInfoBody have been defined.

適用対象