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 구현을 재정의 I.M()M() 하고 별도의 명시적 구현을 제공하는 파생 클래스 C 가 포함된 인터페이스 I 가 포함되어 있습니다.

코드 예제의 메서드는 main() 파생 클래스 C를 내보내는 방법을 보여줍니다. 의 재정의 A.M() 는 동일한 서명이 있는 메서드 M() 를 내보내기만 하면 수행됩니다. 그러나 별도의 구현I.M()을 제공하려면 메서드 본문을 정의한 다음 메서드를 DefineMethodOverride 사용하여 해당 메서드 본문을 를 나타내는 I.M()MethodInfo 연결해야 합니다. 메서드 본문의 이름은 중요하지 않습니다.

코드 예제에서는 내보낸 클래스의 instance 만듭니다. 에 대한 I.M()개체를 MethodInfo 가져오고 이를 사용하여 내보낸 클래스의 명시적 인터페이스 구현을 호출합니다. 그런 다음 에 대한 개체를 MethodInfoA.M()가져오고 이를 사용하여 해당 메서드의 내보낸 클래스 재정의를 호출합니다.

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
'

설명

이 메서드를 사용하여 메서드 재정의 또는 인터페이스 구현을 내보내지 마세요. 기본 클래스의 메서드를 재정의하거나 인터페이스의 메서드를 구현하려면 코드 예제에 설명된 대로 재정의 또는 구현할 메서드와 이름과 시그니처가 같은 메서드를 내보내기만 하면 됩니다.

DefineMethodOverride 메서드 본문과 메서드 선언의 이름이 다를 때 메서드가 사용됩니다. 예를 들어 클래스는 기본 클래스 메서드를 재정의하고 코드 예제에 설명된 대로 동일한 이름을 가진 인터페이스 멤버에 대해 별도의 구현을 제공할 수도 있습니다.

DefineMethodOverridemethodimpl메타데이터 토큰 쌍으로 구성된 를 정의합니다. 한 토큰은 구현을 가리키고 다른 토큰은 본문이 구현하는 선언을 가리킵니다. 메서드 impl이 정의된 형식에서 본문을 정의해야 하며 본문은 가상(Overridable Visual Basic의 경우)이어야 합니다. 선언은 형식으로 구현된 인터페이스에 정의된 메서드, 파생 클래스의 메서드 또는 형식에 정의된 메서드에 대해 수행할 수 있습니다. 선언이 인터페이스에만 있는 경우 인터페이스에 대해 정의된 슬롯이 변경됩니다. 기본 형식의 메서드에 대한 선언이 이루어지면 메서드의 슬롯이 재정의되고 재정의된 메서드에 대한 중복 항목도 바뀝니다. 재정의된 메서드는 선언된 실제 메서드일 수 없습니다. 메서드가 동일한 형식에 있으면 슬롯이 대체되고 대체된 메서드에 대한 중복 항목이 재정의됩니다.

참고

메서드 임프에 대한 자세한 내용은 ECMA C# 및 공용 언어 인프라 표준 및 표준 ECMA-335 - CLI(공용 언어 인프라)의 ECMA 파티션 II 메타데이터 설명서를 참조 MethodImpl 하세요.

중요

메서드가 DefineMethodOverride 호출된 후에는 의 methodInfoBody 일부 기능을 변경할 수 없습니다. 예를 들어 메서드를 사용하여 SetGenericParameterAttributes 의 제네릭 형식 매개 변수 methodInfoBody 에 특성을 적용할 수 없습니다. 메서드를 DefineMethodOverride 사용해야 하는 경우 의 methodInfoBody 모든 특성이 정의된 후에 이 작업을 수행합니다.

적용 대상