2010-01-23 3 views
4

다른 유형의 대리자가 포함 된 목록을 만들 수 있습니까? 예를 들어 considere있는이 두 대표 :대리자의 이성 생성 목록

class MyEventArg1 : EventArgs {} 
class MyEventArg2 : EventArgs {} 

EventHandler<MyEventArgs1> handler1; 
EventHandler<MyEventArgs2> handler2; 

나는 그런 식으로 뭔가를 싶습니다

List<EventHandler<EventArgs>> handlers = new List<EventHandler<EventArgs>>(); 

handlers.Add((EventHandler<EventArgs>)handler1); 
handlers.Add((EventHandler<EventArgs>)handler2); 

그러나 다른 한 대표의 캐스트가 가능 보인다 없습니다. 목표는 대리자를 호출하지 않도록 목록에 저장하는 것입니다. 자동으로 등록을 취소합니다.

감사

답변

1

당신은 generics variance에 C# 4.0 덕분에이에 할 수있을 것입니다하지만 그때까지 당신은 다른 방법 (아마도 ArrayList)를 찾아야합니다.

+0

차이가 도움이되는지 확실하지 않습니다. 'EventHandler <>'는 .NET에서 불변하게 정의됩니다. – nawfal

1

예, 작동하지 않습니다. 대리자는 완전히 관련없는 유형입니다. 일반적으로 generic 형식은 System.Object 만 공통 기본 형식으로 사용합니다. 하지만 여기에서는 대리인이므로 List<Delegate>에 저장할 수 있습니다. 나는 당신이 그들을 등록하지 못하게하는 것을 도울 것이라고 의심합니다. 하지만 그 코드가 어떻게 생겼는지 상상할 수는 없습니다.

0

일반적인 대리자 선언에서 특정 유형 매개 변수가 공변 적이거나 반항 적이어야 지정이 가능합니다. 그러면 후속 지정 유형을 허용 할 수 있습니다. 불행히도 멀티 캐스트 대리자의 내부 구현은 서로 다른 유형의 대리자를 결합 할 수 없게합니다 ("단순한"대리자는 메서드 포인터와 해당 대상에 대한 참조와 함께 형식에 대한 정보를 보유하고 있으며 형식에 대한 멀티 캐스트 위임 정보 결합 된 각 대리자에 대한 메서드 포인터 및 대상 참조를 보유하지만 결합 된 원래 대리자에 대한 참조는 보유하지 않으며 형식에 대한 정보도 보유하지 않습니다. 따라서 EventHandler<DerivedEventArgs>EventHandler<EventArgs>을 결합하려는 시도는 런타임에 실패합니다. EventHandler<T>T에 대한 contravariant했다

경우, 시도는 EventHandler<DerivedEventArgs> 컴파일 것이라고 예상하는 표준 이벤트 AddHandler 방법에 EventHandler<EventArgs>를 통과하고, 다른 핸들러가 등록되어 있지 않은 경우, EventHandler<EventArgs>Delegate.Combine D 것 때문에도 성공할 것 null으로 변경되어 이벤트의 위임 필드에 EventHandler<EventArgs>으로 저장됩니다. 불행하게도 EventHandler<DerivedEventArgs> (실제로 예상되는 유형 임)을 추가하려는 시도는 해당 유형이 결합되는 위임자와 일치하지 않으므로 실패합니다. Microsoft는이 동작이 최소 경악의 원칙을 위반할 것이라고 판단했습니다 ("잘못된"대리인을 전달하면 문제가 발생하며 이후 대리인이 전달 될 때 전달해야 함). 가능성을 최소화하기로 결정했습니다. 이 시나리오는 유일한 구독 인 경우 해당 동작이 성공할 수는 있지만 EventHandler<DerivedEventArgs>을 예상하는 처리기에 EventHandler<EventArgs>을 전달하려고하면 컴파일이 실패합니다.

관련 문제