Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
1시간 9분 13초
C#에서 이벤트는 많은 개발자가 사용하는 기본적인 개념이지만, 특히 자신만의 이벤트를 생성하는 경우 완전히 이해하지 못하는 경우가 많습니다. Tim Corey는 그의 비디오 " C# 이벤트 - 애플리케이션에서 이벤트 생성 및 사용 "에서 이벤트를 생성하고 사용하는 방법에 대한 포괄적인 가이드를 제공하며, 모범 사례와 고급 기능을 살펴봅니다.
이 글에서는 C# 이벤트에 대해 자세히 살펴보겠습니다. 이벤트의 구문, 정의 방법, 그리고 Tim Corey의 비디오 예제를 통해 일반적인 프로그래밍 문제를 해결하는 데 어떻게 도움이 되는지 알아보겠습니다. C#에서 이벤트 처리를 이해하는 것은 반응형 애플리케이션을 구축하는 데 필수적이며, 이 글은 사용자 지정 오류 로깅, 예외 처리 및 이벤트 기반 프로그래밍의 핵심 개념을 파악하는 데 도움이 될 것입니다.
C#을 비롯한 프로그래밍 언어에서 이벤트는 이벤트 기반 프로그래밍에서 매우 중요한 역할을 하며, 애플리케이션이 사용자 상호 작용이나 시스템 변경과 같은 작업에 반응할 수 있도록 해줍니다. 다른 프로그래밍 언어와 비교했을 때, C#은 이벤트 처리에 구조화된 접근 방식을 제공하므로 빠르고 작은 애플리케이션에 이상적입니다. C#에서 이벤트는 특정 동작에 의해 발생하며, 이러한 동작은 원하는 작업을 수행하기 위해 해당 이벤트 핸들러를 호출합니다.
Tim은 대부분의 개발자가 C#의 이벤트에 익숙하지만 사용자 지정 이벤트를 만드는 방법은 모를 수 있다고 설명하며 이야기를 시작합니다. 이 비디오의 목표는 이벤트를 소개하고, 사용자 지정 이벤트를 만드는 과정을 안내하고, 이벤트의 기능을 설명하고, 모범 사례를 제시하는 것입니다.
Tim은 Windows Forms(WinForms)로 제작된 간단한 은행 애플리케이션을 사용하여 이벤트를 시연합니다. 이 애플리케이션은 잔액 조회 및 거래 기록 등 한 고객에 대한 기본적인 은행 업무를 시뮬레이션합니다.
애플리케이션 개요 :
주요 양식 :
거래 양식 :
팀은 데모 뱅킹 애플리케이션의 백엔드 코드를 설명합니다.
고객 등급 :
계정 분류 :
예치금 및 결제 처리 :
초과인출 보호 :
코드 예시는 팀 코리의 영상에서 3분 18초부터 18분 27초까지 코드를 설명하는 부분을 직접 참고하시면 됩니다.
이 섹션에서 Tim Corey는 Windows Forms의 버튼 클릭 이벤트 작동 방식을 자세히 살펴보고 이러한 이벤트가 어떻게 연결되고 어떻게 작동하는지 설명했습니다.
팀은 윈도우 폼 애플리케이션에서 흔히 볼 수 있는 버튼 클릭 이벤트 개념을 설명하는 것으로 이야기를 시작합니다. 디자이너에서 버튼을 두 번 클릭하면 Visual Studio는 클릭 이벤트에 대한 이벤트 처리기 메서드를 자동으로 생성합니다.
이벤트 핸들러 메서드 :
private void recordTransactionButton_Click(object sender, EventArgs e)
{
// Code to handle the button click event
}
이벤트 준비 :
this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);AddHandler Me.recordTransactionButton.Click, AddressOf Me.recordTransactionButton_ClickTim은 C#에서 사용자 지정 이벤트를 만드는 방법을 설명하며, 이벤트가 트리거될 Account 클래스부터 시작합니다.
이벤트 정의하기 :
public event EventHandler<string> RaiseTransactionApprovedEvent;Public Event RaiseTransactionApprovedEvent As EventHandler(Of String)이벤트 발생시키기 :
this)와 이벤트 데이터(이 경우, 문자열)입니다.private void OnTransactionApproved(string transactionName)
{
RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
}
연결 및 이벤트 처리 :
account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
private void Account_RaiseTransactionApprovedEvent(object sender, string e)
{
// Code to handle the event
}
팀은 거래 승인과 같은 특정 작업이 발생할 때 브라우저 UI를 자동으로 업데이트하기 위해 이벤트를 사용하는 방법을 설명합니다.
모금 행사 :
public void AddDeposit(decimal amount, string depositName)
{
// Code to add deposit
RaiseTransactionApprovedEvent?.Invoke(this, depositName);
}
사용자 인터페이스에서 이벤트 구독하기 :
public MainForm()
{
InitializeComponent();
account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent;
}
private void Account_RaiseTransactionApprovedEvent(object sender, string e)
{
// Update the UI with the new transaction
}
Tim Corey는 C#에서 이벤트를 발생시킬 때 ?.Invoke() 구문을 사용하는 방법을 설명합니다. 이러한 최신 접근 방식은 코드를 단순화하고 스레드 안전성을 보장합니다.
Invoke 앞에 있는 물음표(?)는 null 조건부 연산자입니다. 이벤트 핸들러를 호출하기 전에 해당 핸들러가 null인지 확인하여 잠재적인 예외 발생을 방지합니다.
전통적인 접근 방식 :
if (RaiseTransactionApprovedEvent != null)
{
RaiseTransactionApprovedEvent(this, depositName);
}
?.Invoke() 를 사용한 최신 접근 방식 :
RaiseTransactionApprovedEvent?.Invoke(this, depositName);RaiseTransactionApprovedEvent?.Invoke(Me, depositName)RaiseTransactionApprovedEvent이(가) null인 경우, 호출은 진행되지 않으며, 사실상 예외를 피할 수 있습니다.장점 :
Tim은 Windows Forms 애플리케이션에서 사용자 지정 이벤트를 수신하고 그에 따라 UI를 업데이트하는 방법을 설명합니다.
이벤트 구독하기 :
customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;AddHandler customer.CheckingAccount.TransactionApprovedEvent, AddressOf CheckingAccount_TransactionApprovedEvent이벤트 핸들러 메서드 :
private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
{
// Update the UI with the new transaction
checkingTransactionsDataSource.DataSource = null;
checkingTransactionsDataSource.DataSource = customer.CheckingAccount.Transactions;
checkingBalanceLabel.Text = customer.CheckingAccount.Balance.ToString("C2");
}
팀은 사용자 지정 이벤트를 생성, 발생 및 처리하는 전체 과정을 실제로 시연합니다.
이벤트 발생시키기 :
private void OnTransactionApproved(string transactionName)
{
RaiseTransactionApprovedEvent?.Invoke(this, transactionName);
}
여러 이벤트 처리 :
public MainForm()
{
InitializeComponent();
customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;
customer.SavingsAccount.TransactionApprovedEvent += SavingsAccount_TransactionApprovedEvent;
}
private void SavingsAccount_TransactionApprovedEvent(object sender, string e)
{
// Update the UI with the new savings transaction
savingsTransactionsDataSource.DataSource = null;
savingsTransactionsDataSource.DataSource = customer.SavingsAccount.Transactions;
savingsBalanceLabel.Text = customer.SavingsAccount.Balance.ToString("C2");
}
애플리케이션 실행 :
팀은 이벤트 디버깅 방법과 이벤트와 함께 전송되는 정보를 검사하는 방법을 보여줍니다.
중단점 설정 :
private void CheckingAccount_TransactionApprovedEvent(object sender, string e)
{
// Breakpoint here
}
디버깅 :
팀 코리는 초과 인출 상황을 처리하는 또 다른 사용자 지정 이벤트를 만들어 데모를 확장했습니다. 이 이벤트는 잔액 부족이 발생했을 때 발생하며, 사용자에게 잔액 부족 금액을 알려줍니다.
Tim은 먼저 Account 클래스에 초과 인출 상황에 대한 새로운 이벤트를 정의합니다.
이벤트 선언 :
public event EventHandler<decimal> OverdraftEvent;Public Event OverdraftEvent As EventHandler(Of Decimal)이벤트 발생시키기 :
if (overdraftSuccessful)
{
OverdraftEvent?.Invoke(this, overdraftAmount);
}
이벤트 준비 :
customer.CheckingAccount.OverdraftEvent += CheckingAccount_OverdraftEvent;AddHandler customer.CheckingAccount.OverdraftEvent, AddressOf CheckingAccount_OverdraftEvent이벤트 처리 :
private void CheckingAccount_OverdraftEvent(object sender, decimal e)
{
errorMessage.Text = $"You had an overdraft protection transfer of {e:C2}";
errorMessage.Visible = true;
}
이벤트 발생 및 표시 :
You had an overdraft protection transfer of $20.44
팀은 동일한 이벤트를 여러 언어와 형식으로 듣는 방법을 설명하며 이벤트의 다양성을 보여줍니다.
다른 양식에 레이블 추가하기 :
<asp:Label ID="errorMessage" runat="server" Visible="false" />
이벤트 참가 신청 :
customer.CheckingAccount.OverdraftEvent += SecondaryForm_OverdraftEvent;AddHandler customer.CheckingAccount.OverdraftEvent, AddressOf SecondaryForm_OverdraftEvent이벤트 처리 :
private void SecondaryForm_OverdraftEvent(object sender, decimal e)
{
errorMessage.Visible = true;
}
동시 이벤트 처리 :
Both the main form and the secondary form display the overdraft message when the event is triggered.
Tim은 메모리 누수를 방지하고 애플리케이션 성능을 제대로 유지하기 위해 이벤트 리스너를 정리하는 것이 중요하다고 강조합니다.
이벤트 구독 취소 :
클래스 인스턴스를 소멸시키거나 폼을 닫기 전에 이벤트 구독을 해제하는 것이 매우 중요합니다.
customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;RemoveHandler customer.CheckingAccount.OverdraftEvent, AddressOf CheckingAccount_OverdraftEvent왜 중요한가 :
명명된 메서드 사용 :
// Good practice: using named methods for event handlers' Good practice: using named methods for event handlers팀 코리는 이벤트를 통해 데이터를 전달하는 최적의 방법, 특히 문자열이나 소수점과 같은 단순 데이터 유형 대신 클래스를 사용하는 이점에 대해 설명합니다.
팀은 이벤트에 단순 데이터 타입을 사용하는 것이 일반적이지 않은 이유와 클래스를 전달하는 것이 일반적으로 더 나은 이유에 대해 논의하는 것으로 이야기를 시작합니다.
유연성 및 확장성 :
클래스를 사용하면 여러 관련 데이터를 이벤트로 전달할 수 있습니다. 나중에 데이터를 더 추가해야 하는 경우 이벤트 시그니처를 변경하지 않고 클래스를 확장하기만 하면 됩니다.
EventArgs 상속 :
Tim은 잔액 부족 이벤트에 대한 사용자 지정 EventArgs 클래스를 만드는 방법을 보여줍니다.
클래스를 정의합니다 .
public class OverdraftEventArgs : EventArgs
{
public decimal AmountOverdrafted { get; private set; }
public string MoreInfo { get; private set; }
public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
{
AmountOverdrafted = amountOverdrafted;
MoreInfo = moreInfo;
}
}
이벤트에서 클래스 사용하기 :
public event EventHandler<OverdraftEventArgs> OverdraftEvent;Public Event OverdraftEvent As EventHandler(Of OverdraftEventArgs)이벤트 발생시키기 :
OverdraftEvent?.Invoke(this, new OverdraftEventArgs(amountNeeded, "Additional info"));OverdraftEvent?.Invoke(Me, New OverdraftEventArgs(amountNeeded, "Additional info"))Tim은 이벤트 데이터가 실수로 수정되는 것을 방지하기 위해 EventArgs 클래스에서 읽기 전용 속성을 사용하는 것이 중요하다고 강조합니다.
수정 방지 :
문제 예시 :
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
{
e.AmountOverdrafted = 1000; // This modification affects all handlers
}
해결책 :
public decimal AmountOverdrafted { get; private set; }
public string MoreInfo { get; private set; }
Tim Corey는 이벤트 데이터 속성에 대해 비공개 setter를 사용하는 규칙에 대한 중요한 예외 사항을 강조합니다. 이 예외는 특정 조건에 따라 거래가 취소될 수 있는 경우와 같이 이벤트 리스너가 이벤트 데이터를 수정할 수 있도록 허용해야 하는 경우에 발생합니다.
Tim은 이벤트 핸들러가 트랜잭션을 취소해야 할 수 있는 예를 제시합니다. 이는 사용자 지정 EventArgs 클래스에 CancelTransaction 속성을 추가함으로써 구현됩니다.
속성 정의 :
public class OverdraftEventArgs : EventArgs
{
public decimal AmountOverdrafted { get; private set; }
public string MoreInfo { get; private set; }
public bool CancelTransaction { get; set; } = false;
public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo)
{
AmountOverdrafted = amountOverdrafted;
MoreInfo = moreInfo;
}
}
이벤트 핸들러에서 속성 설정하기 :
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
{
if (denyOverdraft.Checked)
{
e.CancelTransaction = true;
}
errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
errorMessage.Visible = true;
}
소스 메서드에서 속성 확인하기 :
if (args.CancelTransaction)
{
return false; // Transaction is canceled
}
팀은 애플리케이션을 더욱 개선하여 상호작용적이고 사용자 친화적으로 만듭니다.
초과인출 관리용 체크박스 추가 :
private void InitializeComponent()
{
this.denyOverdraft = new System.Windows.Forms.CheckBox();
// Initialize other controls
this.denyOverdraft.Text = "Stop Overdrafts";
this.denyOverdraft.CheckedChanged += new System.EventHandler(this.denyOverdraft_CheckedChanged);
}
체크박스 상태 처리 :
private void denyOverdraft_CheckedChanged(object sender, EventArgs e)
{
if (denyOverdraft.Checked)
{
// Logic to stop overdraft transactions
}
}
이벤트 핸들러 업데이트 :
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e)
{
if (denyOverdraft.Checked)
{
e.CancelTransaction = true;
}
errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}";
errorMessage.Visible = true;
}
팀 코리는 C#에서 이벤트를 다룰 때의 핵심 사항과 모범 사례를 요약하며 튜토리얼을 마무리합니다.
이벤트 리스너 제거 :
customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;RemoveHandler customer.CheckingAccount.OverdraftEvent, AddressOf CheckingAccount_OverdraftEventEventArgs 상속 사용 :
읽기 전용 속성에 대한 비공개 설정자 :
이벤트 핸들러 구문 :
널 조건 연산자 :
Tim Corey의 C# 이벤트 에 대한 종합적인 튜토리얼은 이벤트를 효과적으로 생성, 처리 및 관리하는 데 유용한 통찰력과 실용적인 예제를 제공합니다. 이러한 모범 사례를 따르면 개발자는 더욱 상호작용적이고 반응성이 뛰어난 애플리케이션을 만들 수 있습니다.
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy