Event modifier
Peponi │ 11/27/2024 │ 4m
C#
SyntaxKeywordModifier
Event modifier
11/27/2024
4m
Peponi
C#
SyntaxKeywordModifier
1. Introduction
event
한정자는 객체에서 사건이 발생했을 때 다른 객체에 알려주는 역할을 한다. 특수한 종류의 멀티캐스트 대리자로 여러 객체에서 구독하는 것이 가능하다.
event
의 처리는 메서드 또는 람다 식을 통해 정의한다. 액세스 한정자를 적용할 수 있으며, 파생 클래스에서 상속받아 재정의 하는 것이 가능하다.
event
는 GUI 및 비동기식 로직 처리 등에 활용된다.
2. Example
public class FooArgs : EventArgs
{
public FooArgs(int a) => A = a;
public int A { get; set; }
}
public class Pub
{
public event EventHandler<FooArgs> FooEvent;
public void Foo() => FooEvent?.Invoke(this, new FooArgs(10));
}
public class Sub
{
Pub Pub;
public Sub(Pub pub)
{
Pub = pub;
// Subscribe
Pub.FooEvent += BarEventHandler;
}
private void BarEventHandler(object sender, FooArgs e) => Console.WriteLine(e.A);
// Cancel subscribe
public void CancelSubscribe() => Pub.FooEvent -= BarEventHandler;
}
3. 파생 클래스에서 event 호출
event
는 파생 클래스에서는 직접 호출이 불가능하다. (CS0070
) 이 때, 부모 클래스의 event
를 호출하기 위해 간접적인 방법을 사용할 수 있다.
public class FooArgs : EventArgs
{
public FooArgs(string message) => Message = message;
public string Message { get; set; }
}
public class Pub
{
public event EventHandler<FooArgs> FooEvent;
protected virtual void RaiseFoo(FooArgs e) => FooEvent?.Invoke(this, e);
}
public class PubD : Pub
{
public PubD()
{
// FooEvent?.Invoke(this, new FooArgs("PubD")); // CS0070
}
public void SendMessage(string message) => RaiseFoo(new FooArgs(message));
// override method
protected override void RaiseFoo(FooArgs e) => base.RaiseFoo(e);
}
internal class Program
{
private static void Main()
{
PubD d = new PubD();
d.FooEvent += D_FooEvent;
d.SendMessage("PubD");
}
private static void D_FooEvent(object? sender, FooArgs e) => Console.WriteLine(e.Message);
}
4. Event override
event
는 virtual, abstract 등을 이용해 여러 활용을 할 수 있다. 아래는 virtual
을 이용한 override 예시를 보여준다.
public class FooArgs : EventArgs
{
public FooArgs(string message) => Message = message;
public string Message { get; set; }
}
public class Pub
{
public virtual event EventHandler<FooArgs> FooEvent;
public virtual void Foo() => FooEvent?.Invoke(this, new FooArgs("Pub"));
}
public class PubE : Pub
{
public override event EventHandler<FooArgs> FooEvent
{
add { base.FooEvent += value; Console.WriteLine("PubE event add"); }
remove { base.FooEvent -= value; Console.WriteLine("PubE event remove"); }
}
}
public class PubFoo : Pub
{
public override event EventHandler<FooArgs> FooEvent;
public override void Foo() => FooEvent?.Invoke(this, new FooArgs("PubFoo"));
}
internal class Program
{
private static void Foo_FooEvent(object? sender, FooArgs e) => Console.WriteLine($"{sender} sent a message : {e.Message}");
private static void Main()
{
Pub pub = new Pub();
pub.FooEvent += Foo_FooEvent;
pub.Foo(); // Program+Pub sent a message : Pub
PubE pubE = new PubE();
pubE.FooEvent += Foo_FooEvent; // PubE event add
pubE.Foo(); // Program+PubE sent a message : Pub
PubFoo pubFoo = new PubFoo();
pubFoo.FooEvent += Foo_FooEvent;
pubFoo.Foo(); // Program+PubFoo sent a message : PubFoo
}
}