EventInfo.AddEventHandler(Object, Delegate) 메서드

정의

이벤트 소스에 이벤트 처리기를 추가합니다.

public:
 virtual void AddEventHandler(System::Object ^ target, Delegate ^ handler);
public virtual void AddEventHandler (object target, Delegate handler);
public virtual void AddEventHandler (object? target, Delegate? handler);
public void AddEventHandler (object target, Delegate handler);
abstract member AddEventHandler : obj * Delegate -> unit
override this.AddEventHandler : obj * Delegate -> unit
Public Overridable Sub AddEventHandler (target As Object, handler As Delegate)
Public Sub AddEventHandler (target As Object, handler As Delegate)

매개 변수

target
Object

이벤트 소스입니다.

handler
Delegate

이벤트가 대상에 의해 발생할 때 호출될 메서드를 캡슐화합니다.

구현

예외

이 이벤트에 public add 접근자가 없는 경우

전달된 처리기를 사용할 수 없는 경우

호출자에게 멤버에 대한 액세스 권한이 없는 경우

참고: Windows 스토어 앱용 .NET 또는 이식 가능한 클래스 라이브러리에서 기본 클래스 예외 를 MemberAccessException대신 catch합니다.

target 매개 변수가 null이고 이벤트가 static이 아닌 경우

또는

EventInfo가 대상에서 선언되지 않은 경우

참고: Windows 스토어 앱용 .NET 또는 이식 가능한 클래스 라이브러리에서 대신 catch Exception 합니다.

예제

다음 예제에서는 클래스의 System.Timers.Timer instance 만들고 동적 어셈블리를 사용하여 이벤트 처리기를 만들고 동적 이벤트 처리기를 연결합니다. 모든 작업은 지연 바인딩을 사용하여 수행됩니다.

Timer instance 형식Object의 변수에 저장되며 에 액세스하는 Timer 모든 코드는 이렇게 늦게 바인딩됩니다. 이 예제에서는 메서드를 Type.GetEvent 사용하여 이벤트를 가져옵니다 Elapsed . 및 속성은 EventHandlerType 이벤트에 대한 대리자 형식을 가져옵니다.

이 예제에서는 대리자 형식의 메서드에 Invoke 대한 를 가져오 MethodInfo 고 instance 대리자의 MethodInfo 서명을 가져옵니다. 그런 다음, 라는 단일 형식 Handler 을 포함하는 하나의 모듈을 사용하여 동적 어셈블리를 만들고 형식에 이벤트를 처리하는 메서드(SharedVisual Basic의 메서드)를 DynamicHandler 제공합니다static.

동적 형식을 만든 후 이 예제에서는 완성된 메서드에 대한 를 가져오 MethodInfo 고 이를 사용하여 대리자 instance 만듭니다. 이 instance 메서드에 AddEventHandler 전달되어 이벤트를 연결합니다. 그런 다음 프로그램이 일시 중지되어 이벤트가 발생할 수 있습니다.

using System;
using System.Reflection;
using System.Reflection.Emit;

public class Example
{
    private static object? timer;

    public static void Main()
    {
        // Get the Timer type.
        Type t = typeof(System.Timers.Timer);
        // Create an instance of the Timer type.
        timer = Activator.CreateInstance(t);

        // Use reflection to get the Elapsed event.
        EventInfo? eInfo = t.GetEvent("Elapsed");

        // In order to create a method to handle the Elapsed event,
        // it is necessary to know the signature of the delegate
        // used to raise the event. Reflection.Emit can then be
        // used to construct a dynamic class with a static method
        // that has the correct signature.

        // Get the event handler type of the Elapsed event. This is
        // a delegate type, so it has an Invoke method that has
        // the same signature as the delegate. The following code
        // creates an array of Type objects that represent the
        // parameter types of the Invoke method.
        //
        Type? handlerType = eInfo?.EventHandlerType;
        MethodInfo? invokeMethod = handlerType?.GetMethod("Invoke");
        ParameterInfo[]? parms = invokeMethod?.GetParameters();
        Type[] parmTypes = new Type[parms?.Length ?? 0];
        for (int i = 0; i < parms?.Length; i++)
        {
            parmTypes[i] = parms[i].ParameterType;
        }

        // Use Reflection.Emit to create a dynamic assembly that
        // will be run but not saved. An assembly must have at
        // least one module, which in this case contains a single
        // type. The only purpose of this type is to contain the
        // event handler method. (You can use also dynamic methods,
        // which are simpler because there is no need to create an
        // assembly, module, or type.)
        //
        AssemblyName aName = new AssemblyName();
        aName.Name = "DynamicTypes";
        AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
        ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
        TypeBuilder tb = mb.DefineType("Handler", TypeAttributes.Class | TypeAttributes.Public);

        // Create the method that will handle the event. The name
        // is not important. The method is static, because there is
        // no reason to create an instance of the dynamic type.
        //
        // The parameter types and return type of the method are
        // the same as those of the delegate's Invoke method,
        // captured earlier.
        MethodBuilder handler = tb.DefineMethod("DynamicHandler",
            MethodAttributes.Public | MethodAttributes.Static,
            invokeMethod?.ReturnType, parmTypes);

        // Generate code to handle the event. In this case, the
        // handler simply prints a text string to the console.
        //
        ILGenerator il = handler.GetILGenerator();
        il.EmitWriteLine("Timer's Elapsed event is raised.");
        il.Emit(OpCodes.Ret);

        // CreateType must be called before the Handler type can
        // be used. In order to create the delegate that will
        // handle the event, a MethodInfo from the finished type
        // is required.
        Type? finished = tb.CreateType();
        MethodInfo? eventHandler = finished?.GetMethod("DynamicHandler");

        // Use the MethodInfo to create a delegate of the correct
        // type, and call the AddEventHandler method to hook up
        // the event.
        if (handlerType is not null && eventHandler is not null)
        {
            Delegate d = Delegate.CreateDelegate(handlerType, eventHandler);
            eInfo?.AddEventHandler(timer, d);
        }

        // Late-bound calls to the Interval and Enabled property
        // are required to enable the timer with a one-second
        // interval.
        t.InvokeMember("Interval", BindingFlags.SetProperty, null, timer, new Object[] { 1000 });
        t.InvokeMember("Enabled", BindingFlags.SetProperty, null, timer, new Object[] { true });

        Console.WriteLine("Press the Enter key to end the program.");
        Console.ReadLine();
    }
}
/* This example produces output similar to the following:

Press the Enter key to end the program.
Timer's Elapsed event is raised.
Timer's Elapsed event is raised.
Timer's Elapsed event is raised.
*/
Imports System.Reflection
Imports System.Reflection.Emit

Public Class Example

    Private Shared timer As Object
    
    Public Shared Sub Main() 
        ' Get the Timer type.
        Dim t As Type = GetType(System.Timers.Timer)
        ' Create an instance of the Timer type.
        timer = Activator.CreateInstance(t)
        
        ' Use reflection to get the Elapsed event.
        Dim eInfo As EventInfo = t.GetEvent("Elapsed")
        
        ' In order to create a method to handle the Elapsed event,
        ' it is necessary to know the signature of the delegate 
        ' used to raise the event. Reflection.Emit can then be
        ' used to construct a dynamic class with a static method
        ' that has the correct signature.
        '
        ' Get the event handler type of the Elapsed event. This is
        ' a delegate type, so it has an Invoke method that has
        ' the same signature as the delegate. The following code
        ' creates an array of Type objects that represent the 
        ' parameter types of the Invoke method.
        '
        Dim handlerType As Type = eInfo.EventHandlerType
        Dim invokeMethod As MethodInfo = handlerType.GetMethod("Invoke")
        Dim parms As ParameterInfo() = invokeMethod.GetParameters()
        '
        ' Note that in Visual Basic you must dimension the array one
        ' unit smaller than the source array in order to get an array
        ' of the same size. This is because Visual Basic adds an extra
        ' element to every array, for ease of use.
        '
        Dim parmTypes(parms.Length - 1) As Type
        Dim i As Integer
        For i = 0 To parms.Length - 1
            parmTypes(i) = parms(i).ParameterType
        Next i
        
        ' Use Reflection.Emit to create a dynamic assembly that
        ' will be run but not saved. An assembly must have at 
        ' least one module, which in this case contains a single
        ' type. The only purpose of this type is to contain the 
        ' event handler method. (You can alsso use dynamic methods, 
        ' which are simpler because there is no need to create an 
        ' assembly, module, or type.)
        Dim aName As New AssemblyName()
        aName.Name = "DynamicTypes"
        Dim ab As AssemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run)
        Dim mb As ModuleBuilder = ab.DefineDynamicModule(aName.Name)
        Dim tb As TypeBuilder = mb.DefineType("Handler", TypeAttributes.Class Or TypeAttributes.Public)
        
        ' Create the method that will handle the event. The name
        ' is not important. The method is Shared ("static" in 
        ' reflection), because there is no reason to create an 
        ' instance of the dynamic type "Handler".
        '
        ' The parameter types and return type of the method are
        ' the same as those of the delegate's Invoke method, 
        ' captured earlier.
        Dim handler As MethodBuilder = tb.DefineMethod("DynamicHandler", MethodAttributes.Public Or MethodAttributes.Static, invokeMethod.ReturnType, parmTypes)
        
        ' Generate code to handle the event. In this case, the 
        ' handler simply prints a text string to the console.
        '
        Dim il As ILGenerator = handler.GetILGenerator()
        il.EmitWriteLine("Timer's Elapsed event is raised.")
        il.Emit(OpCodes.Ret)
        
        ' CreateType must be called before the Handler type can
        ' be used. In order to create the delegate that will
        ' handle the event, a MethodInfo from the finished type
        ' is required.
        Dim finished As Type = tb.CreateType()
        Dim eventHandler As MethodInfo = finished.GetMethod("DynamicHandler")
        
        ' Use the MethodInfo to create a delegate of the correct 
        ' type, and call the AddEventHandler method to hook up 
        ' the event.
        Dim d As [Delegate] = [Delegate].CreateDelegate(handlerType, eventHandler)
        eInfo.AddEventHandler(timer, d)
        
        ' Late-bound calls to the Interval and Enabled property 
        ' are required to enable the timer with a one-second
        ' interval.
        t.InvokeMember("Interval", BindingFlags.SetProperty, Nothing, timer, New [Object]() {1000})
        t.InvokeMember("Enabled", BindingFlags.SetProperty, Nothing, timer, New [Object]() {True})
        
        Console.WriteLine("Press the Enter key to end the program.")
        Console.ReadLine()
    
    End Sub 
End Class 
' This example produces output similar to the following:
'      Press the Enter key to end the program.
'      Timer's Elapsed event is raised.
'      Timer's Elapsed event is raised.
'      Timer's Elapsed event is raised.

설명

이 메서드는 대상 개체에서 이벤트를 동기화하는 대리자를 추가하려고 시도합니다.

대상 매개 변수에 의해 이벤트가 발생할 때마다 처리기에 의해 캡슐화된 메서드 또는 메서드가 호출됩니다.

프로그램이 이미 컴파일된 후 형식을 로드할 때 C# += 구문 또는 Visual Basic WithEventsHandles 키워드를 사용하여 이벤트를 연결할 수 없는 경우 메서드를 사용할 AddEventHandler 수 있습니다.

적용 대상

추가 정보