[C#] 표준 이벤트 패턴
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!
.NET에서는 이벤트 데이터를 전달할 때 EventArgs를 상속한 클래스를 사용하는 것이 표준 패턴이다. 이벤트는 EventHandler 형태로 선언하며, 여기서 TEventArgs가 함께 전달할 이벤트 데이터다.
// 이벤트 데이터 클래스
class PriceChangedEventArgs : EventArgs
{
public decimal OldPrice { get; }
public decimal NewPrice { get; }
public decimal ChangePercent { get; }
public PriceChangedEventArgs(decimal oldPrice, decimal newPrice)
{
OldPrice = oldPrice;
NewPrice = newPrice;
if (oldPrice != 0)
{
ChangePercent = (newPrice - oldPrice) / oldPrice * 100;
}
}
}
class Stock
{
private string _symbol;
private decimal _price;
// 표준 이벤트 패턴: EventHandler<TEventArgs>
public event EventHandler<PriceChangedEventArgs> PriceChanged;
public Stock(string symbol, decimal initialPrice)
{
_symbol = symbol;
_price = initialPrice;
}
public decimal Price
{
get => _price;
set
{
if (_price == value)
{
return;
}
decimal oldPrice = _price;
_price = value;
// 이벤트 발생
OnPriceChanged(new PriceChangedEventArgs(oldPrice, _price));
}
}
// protected virtual로 선언하여 상속 시 재정의 가능
protected virtual void OnPriceChanged(PriceChangedEventArgs e)
{
PriceChanged?.Invoke(this, e);
}
public override string ToString()
{
return $"{_symbol}: {_price:C}";
}
}
class Program
{
static void Main()
{
Stock msStock = new Stock("MSFT", 100.00m);
// 표준 패턴: sender와 EventArgs를 받음
msStock.PriceChanged += (sender, e) =>
{
Stock stock = (Stock)sender;
Console.WriteLine($"[{stock}]");
Console.WriteLine($" 이전 가격: {e.OldPrice:C}");
Console.WriteLine($" 현재 가격: {e.NewPrice:C}");
Console.WriteLine($" 변동률: {e.ChangePercent:F2}%");
Console.WriteLine();
};
msStock.Price = 110.00m;
msStock.Price = 105.50m;
msStock.Price = 120.00m;
}
}
이벤트(PriceChanged)를 직접 Invoke하지 않고, OnPriceChanged라는 virtual 메서드를 따로 만들어 그 안에서 호출한다. 이렇게 한 단계 감싸두면 상속받은 자식 클래스가 이 메서드를 재정의해서 이벤트 발생 시점의 동작을 바꿀 수 있다.
public sealed class ValueChangedEventArgs : EventArgs
{
public DataSnapshot Snapshot { get; private set; }
public DatabaseError DatabaseError { get; private set; }
internal ValueChangedEventArgs(DataSnapshot snapshot)
{
Snapshot = snapshot;
}
internal ValueChangedEventArgs(DatabaseError error)
{
DatabaseError = error;
}
}
EventArgs를 상속받았으므로 표준 패턴으로 만들어진 이벤트 클래스라는 것을 확인할 수 있다
생성자로 snapshot을 받으면 정상 상황이고 DatabaseError를 받으면 에러 상황인 것이다
private void OnValueChanged(object sender, ValueChangedEventArgs args)
{
if (args.DatabaseError != null)
{
Debug.LogError($"[Leaderboard] 리스너 오류: {args.DatabaseError}");
return;
}
List<LeaderboardEntry> leaderboard = ParseEntries(args.Snapshot);
DispatchUpdateAsync(leaderboard).Forget();
}
여기서 이벤트 OnValueChanged는 표준 시그니처 void Handler(object sender, ValueChangedEventArgs args)를 그대로 따른다.
260617실습(제너릭,인터페이스)
비동기 프로그래밍(C Sharp)
서로 다른 객체가 서로의 상태를 알아야하는 상황은 굉장히 자주 나오고, 어찌보면 객체지향 프로그래밍의 대부분의 고민이 여기서 비롯되는 것도 같다. 내가 지금껏 개발하며 사용한 패턴이나 전략들의 장단점을 모았다. 싱글턴 클래스 개념 단 한 개의 인스턴스만 존재하도록 하면서, static 으로 전역적인 접근이 가능하도록 하는 클래스. 장점 구현이 매우 빠르다.
260617실습(제너릭,인터페이스)
비동기 프로그래밍(C Sharp)


서로 다른 객체가 서로의 상태를 알아야하는 상황은 굉장히 자주 나오고, 어찌보면 객체지향 프로그래밍의 대부분의 고민이 여기서 비롯되는 것도 같다. 내가 지금껏 개발하며 사용한 패턴이나 전략들의 장단점을 모았다. 싱글턴 클래스 개념 단 한 개의 인스턴스만 존재하도록 하면서, static 으로 전역적인 접근이 가능하도록 하는 클래스. 장점 구현이 매우 빠르다.