다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.
이벤트의 null 예외
이벤트를 호출하였을때, 결합된 이벤트 핸들러가 없다면 nullReference 예외가 발생한다.
때문에 예전에는 다음과 같은 방식으로 코드를 작성하였다.
public void Test()
{
if(MyEvent != null)
MyEvent(this, counter);
}
그런데 이벤트를 발생시키는 코드를 수행하기 직전에 다른 쓰레드가 이벤트 핸들러의 등록을 취소한다면 이벤트 핸들러는 null 예외를 발생시킬 것이다. (재현도 어렵고 극단적인 케이스기는 하다)
이 때문에 멀티스레드 환경에서는 다음과 같은 코드로 오류를 방지했다.
public void Test()
{
var tempHandler = MyEvent;
if(tempHandler != null)
tempHandler(this, counter);
}
지역변수에 이벤트 핸들러를 얕은 복사하여, 외부에서 다른 스레드가 원본의 이벤트 구독을 취소하더라도
복사된 지역변수에서는 남아있기때문에 정상호출된다.
null 조건 연산자
- 해결책은 간단하다. null 조건 연산자를 사용하여 안전하게 이벤트 핸들러를 호출할 수 있다.
- ?. 연산자를 이용하여 이벤트를 발생시킬때는 이벤트 이름뒤에 ()를 붙여 호출할 수 없다. Invoke로 호출해야한다.
public void Test()
{
MyEvent?.Invoke(this, counter);
}
결론
- 이벤트를 if문으로 null 검사하는 것은 구식 방식이며, 반드시 ?. 연산자를 이용하는 방식을 사용하라.
'🌍 C# Study > 이펙티브 C#' 카테고리의 다른 글
[10] 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라 (0) | 2021.04.23 |
---|---|
[09] 박싱과 언박싱을 최소화하라 (0) | 2021.04.23 |
[07] 델리게이트를 이용하여 콜백을 표현하라 (0) | 2021.04.23 |
[06] nameof() 연산자를 적극 활용하라 (0) | 2021.04.22 |
[05] 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라 (0) | 2021.04.22 |