2011-08-16 3 views
2

"이벤트"는 따옴표로 묶었습니다. 사실 형식이 아닌 설탕 설탕이라는 점을 알고 있기 때문입니다."이벤트"를 참조로 전달하는 것과 동일한 작업을 수행 할 수있는 방법이 있습니까?

나는 다른 클래스에서 일치하는 이벤트에 단순히 연결되어있는 이벤트가 있습니다. 그래서 이벤트가 발생할 때, 통로는

모금처럼 -> 프록시 -> 나는이 같은 일반적인 패턴이 Proxy 클래스에 따라서 가입자

:

Raiser.SomeEvent += 
    (_, args) => 
    { 
     if (this.SomeEvent != null) 
      this.SomeEvent(this, args); 
    }; 

이 정돈하기 위해 내

public static EventHandler GetHandlerDelegate(EventHandler handler, Object sender) 
{ 
    return 
     (_, args) => 
     {     
      if (handler != null) 
       handler(sender, args); 
     }; 
    }  

그리고 프록시에 난 그냥 수행 할 수 있습니다 : 코드 나는 위의 이벤트 호출 코드를 래핑하는 새로운 대리자를 반환하는 다른 방법이 밖으로 이동하고 싶어

Raiser.SomeEvent += GetHandlerDelegate(this.SomeEvent, this); 

어느 쪽이 훨씬 더 깔끔합니다.

위의 호출을 후에 Proxy.SomeEvent에 을 구독하기로 결정하지 않는 한 괜찮습니다. 불행히도 내가 기대했던 것처럼 "이벤트"를 참조로 전달하지는 않습니다. 이제는 호출 목록을 전달하는 중임을 이해하므로 OtherClass.SomeEvent이 발생하고 익명 메서드가 호출되어 해당 이벤트에 추가 된 대리자 (해당 대리자)가 호출됩니다 (). GetHandlerDelegate()를 호출하면이 호출됩니다. 실제로 현재 상황에서는 충분하지만, 그렇게 코딩하는 것은 허용되지 않습니다.

다른 질문을 읽었습니다. Reactive Extensions라는 도움이 될만한 것이 있지만 지금은 좀 더 간단한 해결책을 찾고 있습니다. (그렇지 않다면, 나는 단지 이것을하지 않을 것입니다.)

내가 말하고자하는 바를 달성 할 수있는 또 다른 방법이 있습니까?


이 질문이 분명하지 않은 경우 명확하게 이해하는 데 도움이되는 my answer을 참조하십시오.

답변

0

일을 내 원래의 목표는 이후 :

Raiser.SomeEvent += GetHandlerDelegate(this.SomeEvent, this); 

은 불가능하다, 나는 타협이 함께 왔어요 :

Raiser.SomeEvent += (_, args) => RaiseEvent(this.SomeEvent, this, args); 

GetHandlerDelegate() 반면이 RaiseEvent()을 이벤트를 발생 대리자를 반환 단순히 (당신이 추측 한) 이벤트를 발생시킵니다.

public static void RaiseEvent(EventHandler _event, Object sender, EventArgs args) 
{ 
    if (_event != null) 
     _event(sender, args); 
} 

그리고 지원하는 이벤트를 사용하여 사용자 정의는 EventArgs는 :

public static void RaiseEvent<TArgs>(EventHandler<TArgs> _event, Object sender, TArgs args) 
    where TArgs : EventArgs 
{ 
    if (_event != null) 
     _event(sender, args); 
} 

나는 정적 도우미 클래스에서 이러한 방법을 넣어, 그래서 실제 호출은 약간 이보다이다; 여기에 예는 다음과 같습니다

ViewControl.OpenFilesetClick += (_, args) => EventHelper.Raise(OpenFilesetClick, this, args); 

(나는 또한() 올리는 방법을 이름을 변경하고 이벤트 이름이 전달되는 것을 선택 this 하락). 이 대안은 읽기 틀림없이 쉬웠다 고려 가치가있는 경우

는하지만 완전히 확신 아니에요 :

ViewControl.OpenFilesetClick += (_, args) => 
{ 
    if (OpenFilesetClick != null) 
     OpenFilesetClick(this, args); 
}; 

을 어쨌든, 이벤트 위임이 작동하는 방법에 대한 자세한 내용을 배울 수있는 재미있는 방법이었다 (또는 어떻게 작동하지 않는지).

3

편집 : 좋아, 이제 요점을 얻었을거야. 사실 아주 간단합니다. 당신은 이벤트를 가지고 프록시를 쓸 수, 다음과 같이 자체 모금 행사에 가입 프록시를해야한다 (단지에 대한 EventHandler - 나는 나중에이 올 것이다) :

Proxy proxy = new Proxy(); 
raiser.SomeEvent += Proxy.Handler; 

// Then in the subscriber... 
proxy.ProxiedEvent += (whatever) 

// And the proxy class... 
public class Proxy 
{ 
    public event EventHandler ProxiedEvent; 

    public void Handler(object sender, EventArgs e) 
    { 
     EventHandler proxied = ProxiedEvent; 
     if (proxied != null) 
     { 
      // Or pass on the original sender if you want to 
      proxied(this, e); 
     } 
    } 
} 

자, 어려움은 일반적으로 작동하도록하는 것입니다. 나는 현재 다소 혼란 스럽긴하지만, 현재 그렇게하는 어떤 방법을 생각할 수는 없습니다.

이것은 당신이 생각하고 있었던 것입니까, 아니면 적어도 당신이 사물에 대해 다른 생각을하도록 도울까요?

+0

존, 대답 해 주셔서 감사합니다. 그러나 단순한 하위 껍데기 필사자로서 나는 묵시적인 세부 사항을 보는 데 어려움을 겪고 있습니다. 즉, 나는 길을 잃었다. 정교하게 칠할 수 있니? 이 문제가 내 문제에 어떻게 적용될 수 있습니까? –

+0

@Charles : 질문을 잘못 이해했을 가능성이 있습니다 ... 지금 당장 따르기가 약간 힘들지만, 그게 내 잘못이라고 생각합니다. 그러나 EventWrapper는 기본적으로 "구독하고 탈퇴 할 수있는 무언가"개념을 추상화하는 방법입니다. 그게 바로 근본적인 사건입니다. 대리자가 아니기 때문에 이벤트 자체를 대리자로 사용할 수는 없습니다. –

+0

나는 내 질문을 제대로 표현하지 못하는 역사가있는 것 같아서 혼란에 책임이 있다고 확신한다. 본질적으로 모든 대리자 _dA_를 메서드에 전달하고 _dA_를 호출하는 새 대리자 _dB_를 가져오고 _dA_의 호출 목록이 변경되면 _dB_을 호출 할 때 _updated_ 호출 목록을 호출하도록합니다. (나는 이벤트를 전혀 사용하지 않고이 문제를 시도했다. 단지 대의원 만이 문제를 해결하는 방법에 대해 정말로 스스로 확인했다.) –