EventHandler를 ConditionalWeakTable에 키로 저장하려고했지만 값에 액세스하려고 시도했지만 찾을 수 없습니다.EventHandler를 Key로 사용하는 조건부 대기 테이블
var eventReceiver = new StateChangedEventReceiver();
var dict = new ConditionalWeakTable<EventHandler<EventArgs>, string>();
dict.Add(eventReceiver.OnStateChanged, "Foobar");
string dummy;
dict.TryGetValue(eventReceiver.OnStateChanged, out dummy); // returns false!!!
StateChangedEventReceiver의 코드는 다음과 같습니다
public class StateChangedEventReceiver
{
public void OnStateChanged(object sender, EventArgs args)
{
}
}
가 나는 사전 예상대로 작동을 사용하여 동일한 동작을 테스트 :
var eventReceiver = new StateChangedEventReceiver();
var dict = new Dictionary<EventHandler<EventArgs>, string>();
dict.Add(eventReceiver.OnStateChanged, "Foobar");
string dummy;
dict.TryGetValue(eventReceiver.OnStateChanged, out dummy); // returns true -> as expected
이유는 무엇입니까?
비교자를 취하는 ConditionalWeakTable의 생성자가 없습니다. WeakEventManager-Class에서 .Net 4.5로 .Net 4.0으로 "포트"(나는 소스 코드가 없음)를 사용하려고하므로 .NET 4.0으로 업데이트 할 수 없습니다. 내가 올바르게 작동하지만 모든 이벤트 처리기를 제거 할 수 없습니다.
WeakEventManager의 공용 인터페이스가 EventHandler-instance를 사용하고 매번 같은 인스턴스를 전달할 수 없기 때문에 동일한 위임 인스턴스를 ConditionalWeakTable에 추가 할 수 없습니다. 어쩌면 고유 한 대리자와 함께 등록 된 모든 이벤트 처리기를 기억할 수 있습니다 (키/값을 가비지 수집 할 수 없기 때문에 사전에 저장하는 것이 효과가 없습니다). –
나는 당신의 생각을 증명하고 당신 말이 맞습니다. 대리자에 메서드를 할당하면 새 delegate-instance가 만들어지는 것을 보았습니다. 문제는 매번 같은 인스턴스를 전달할 수 없다는 것입니다. –
두 가지 아이디어가 있습니다 : 당신이 보았던 모든 이벤트 핸들러 (오브젝트 수명에 영향을 미치지 않는 약한 참조를 사용하는 것)를 기억하거나 리플렉션을 사용하여'ConditionalWeakTable'과'DependentHandle'을 열어서 커스텀'ConditionalWeakTable'을 빌드하십시오. 이 코드가 프레임 워크의 다음 주요 버전을 깨뜨릴 것으로 기대하십시오. 당신은'ConditionalWeakTable'의 소스 코드로 시작하여'DependentHandle'에 대한 개인 호출 만하면됩니다. – usr