이 문서에서는 대리자, EventHandler 대리자 및 사용자 지정 대리자를 사용하여 EventHandler<TEventArgs> .NET의 이벤트로 작업하는 방법을 보여 줍니다. 여기에는 데이터가 있는 이벤트와 없는 이벤트에 대한 예제가 있습니다.
사전 요구 사항
이벤트 문서의 개념을 숙지합니다.
데이터 없이 이벤트 발생시키기
이러한 단계는 실행 중인 합계가 임계값에 Counter 도달하거나 초과할 때 ThresholdReached 이벤트를 발생시키는 클래스를 만듭니다.
대리자를 사용하여 이벤트를 선언합니다 EventHandler .
이벤트가 처리기에 데이터를 전달하지 않는 경우에 사용합니다
EventHandler.public event EventHandler? ThresholdReached;Public Event ThresholdReached As EventHandlerprotected virtual메서드를 추가하여 이벤트를 발생시키고, Visual Basic에서는Protected Overridable를 사용합니다.이 패턴을 사용하면 파생 클래스가 대리자를 직접 호출하지 않고 이벤트 발생 동작을 재정의할 수 있습니다. C#에서 null 조건부 연산자(
?.)를 사용하여 구독자 없음을 방지합니다(Visual BasicRaiseEvent에서는 자동으로 처리함).protected virtual void OnThresholdReached(EventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As EventArgs) RaiseEvent ThresholdReached(Me, e) End Sub조건이 충족되면 raise 메서드를 호출합니다.
이 이벤트는 데이터를 전달하지 않으므로 전달 Empty 합니다.
if (_total >= _threshold) { OnThresholdReached(EventArgs.Empty); }If (_total >= _threshold) Then OnThresholdReached(EventArgs.Empty) End If연산자를 사용하여
+=이벤트를 구독합니다(Visual Basic의AddHandler경우).c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReached이벤트 처리기 메서드를 정의합니다.
해당 서명은 대리자와 EventHandler 일치해야 합니다. 첫 번째 매개 변수는 이벤트 원본이고 두 번째 매개 변수는 다음과 같습니다 EventArgs.
static void c_ThresholdReached(object? sender, EventArgs e) { Console.WriteLine("The threshold was reached."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As EventArgs) Console.WriteLine("The threshold was reached.") Environment.Exit(0) End Sub
다음 예제에서는 전체 구현을 보여줍니다.
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
}
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event EventHandler? ThresholdReached;
}
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As EventHandler
End Class
데이터를 사용하여 이벤트를 발생시키다
이러한 단계는 이전 Counter 예제를 확장하여 임계값과 도달한 시간을 포함하는 이벤트를 발생합니다.
에서 상속되는 이벤트 데이터 클래스를 정의합니다.EventArgs
처리기에 전달하려는 각 데이터 조각에 대한 속성을 추가합니다.
public class ThresholdReachedEventArgs : EventArgs { public int Threshold { get; set; } public DateTime TimeReached { get; set; } }Class ThresholdReachedEventArgs Inherits EventArgs Public Property Threshold As Integer Public Property TimeReached As Date End Class대리자를 사용하여 이벤트를 선언하고 EventHandler<TEventArgs> 이벤트 데이터 클래스를 형식 인수로 전달합니다.
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)protected virtual메서드를 추가하여 이벤트를 발생시킵니다 (Protected Overridable는 Visual Basic).이 패턴을 사용하면 파생 클래스가 대리자를 직접 호출하지 않고 이벤트 발생 동작을 재정의할 수 있습니다. C#에서 null 조건부 연산자(
?.)를 사용하여 구독자 없음을 방지합니다(Visual BasicRaiseEvent에서는 자동으로 처리함).protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) RaiseEvent ThresholdReached(Me, e) End Sub이벤트 데이터 개체를 채우고 조건이 충족되면 raise 메서드를 호출합니다.
if (_total >= _threshold) { ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); }If (_total >= _threshold) Then Dim args As New ThresholdReachedEventArgs With { .Threshold = _threshold, .TimeReached = Date.Now } OnThresholdReached(args) End If연산자를 사용하여
+=이벤트를 구독합니다(Visual Basic의AddHandler경우).c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReached이벤트 처리기를 정의합니다.
두 번째 매개 변수 유형은 EventArgs 대신
ThresholdReachedEventArgs으로, 이는 처리기가 이벤트 데이터를 읽을 수 있게 해줍니다.static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e) { Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) Environment.Exit(0) End Sub
다음 예제에서는 전체 구현을 보여줍니다.
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
}
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
End Class
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
이벤트에 대한 사용자 지정 대리자 선언
제네릭을 사용할 수 없는 레거시 코드에서 클래스를 사용할 수 있도록 하는 등 드문 시나리오에서만 사용자 지정 대리자를 선언합니다. 대부분의 경우 이전 섹션에 표시된 대로 사용합니다 EventHandler<TEventArgs> .
사용자 지정 대리자 형식을 선언합니다.
대리자 서명은 이벤트 처리기 서명과 일치해야 합니다. 두 매개 변수: 이벤트 원본(
objectVisual Basic의Object경우) 및 이벤트 데이터 클래스:public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)사용자 지정 대리자 형식을 사용하여 이벤트를 선언하고 EventHandler<TEventArgs>대신 이를 활용하십시오.
public event ThresholdReachedEventHandler? ThresholdReached;Public Event ThresholdReached As ThresholdReachedEventHandlerprotected virtual메서드(Protected Overridable는 Visual Basic의 경우) 를 추가하여 이벤트를 발생시킵니다.C#에서 null 조건부 연산자(
?.)를 사용하여 구독자 없음을 방지합니다(Visual BasicRaiseEvent에서는 자동으로 처리함).protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { ThresholdReached?.Invoke(this, e); }Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) RaiseEvent ThresholdReached(Me, e) End Sub이벤트 데이터 개체를 채우고 조건이 충족되면 raise 메서드를 호출합니다.
if (_total >= _threshold) { ThresholdReachedEventArgs args = new(); args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); }If (_total >= _threshold) Then Dim args As New ThresholdReachedEventArgs With { .Threshold = _threshold, .TimeReached = Date.Now } OnThresholdReached(args) End If연산자를 사용하여
+=이벤트를 구독합니다(Visual Basic의AddHandler경우).c.ThresholdReached += c_ThresholdReached;AddHandler c.ThresholdReached, AddressOf c_ThresholdReached이벤트 처리기를 정의합니다.
처리기 서명은 보낸 사람 및 두 번째 매개 변수의 이벤트 데이터 클래스에 대한 사용자 지정 대리
object자와 일치해야 합니다.static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e) { Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}."); Environment.Exit(0); }Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) Environment.Exit(0) End Sub
다음 예제에서는 전체 구현을 보여줍니다.
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
public event ThresholdReachedEventHandler? ThresholdReached;
}
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
End Sub
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
Public Event ThresholdReached As ThresholdReachedEventHandler
End Class
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
관련 콘텐츠
.NET