StackOverflow
https://stackoverflow.com/questions/937181/c-sharp-pattern-to-prevent-an-event-handler-hooked-twice
event, Action은 꽤 많이 사용하는 편인데
가끔씩 초기화 코드가 중복되면서 이벤트가 중복 호출되는 문제가 발생하기 쉽다.
그런데 이런 휴먼에러가 발생하면 이벤트 쪽은 이원화되어 있기 때문에 오류를 발견하기 어렵다..
1. 방법 1 : 명시적으로 제거하기
using System.Linq;
private EventHandler foo;
public event EventHandler Foo
{
add
{
if (foo == null || !foo.GetInvocationList().Contains(value))
foo += value;
}
remove
{
foo -= value;
}
}
2. 방법 2 : 언제나 초기화 전에 제거하기
중요한 사실. -=은 발견되지 않아도 예외가 발생하지 않는다.
때문에 많은 개발자들이 체인을 걸기 전에 빼는 방식으로 구현한다고 함.
private void OnEnable()
{
Value.onValueChanged -= OnValueCallback;
Value.onValueChanged += OnValueCallback;
}
private void OnDisable()
{
Value.onValueChanged -= OnValueCallback;
}
다음과 같이 이벤트 핸들러 내부에서 처리하는 방법도 존재한다!
private EventHandler _foo;
public event EventHandler Foo
{
add
{
_foo -= value;
_foo += value;
}
remove
{
_foo -= value;
}
}
3. 단일 이벤트라면 그냥 대입 연산자 쓰기
- 다른 이벤트가 체인 될게 아니라면 그냥 대입 연산자를 써버리는 방법도 있다.
연결되어있던 모든 이벤트들의 레퍼런스가 사라지며, 새로 대입한 레퍼런스로 바뀐다.
- 버튼은 일반적으로 한 개의 이벤트만 가지기 때문에, 주로 버튼에 이벤트 할당할 때 사용하게 된다.
private void OnEnable()
{
Value.onValueChanged = OnValueCallback;
}
private void OnDisable()
{
Value.onValueChanged -= OnValueCallback;
}
마치며..
사실 이벤트 order를 가진 프로퍼티를 만들어볼까 하고 만지작거리고 있었는데,
이벤트는 이원화되어야하며, 순서를 가진다면 당신은 무언가 잘못 짠 것입니다.
라길래 순서 없는 버전까지만 하는 걸로!
'🌍 C# Study > C# 케이스 스터디' 카테고리의 다른 글
Float.Parse not in a correct format 문화권 문제 (2) | 2021.11.21 |
---|---|
C# switch 내부 when 절 (0) | 2021.11.02 |
C# string to enum (string 값 enum으로 변환하기) System.Enum.Parse (0) | 2021.09.21 |
C# 인스턴스 초기화 순서 정리 (0) | 2021.05.09 |
HashSet vs HashTable vs Dictionary (0) | 2021.04.30 |