2013-04-12 12 views
1

이벤트에 가입 (그리고 덜 중요하게 구독 취소)을위한 유창한 확장 방법을 만들고 싶습니다. object.WhenSomethingChanges.RespondBy(DoingThisOtherThing);이벤트 내에서 구독/구독 취소 (추가/제거) 확장 방법

을 대신 이런 : 그건 내가이 일을하고자하는 += new Eventhandler(Method)

대신에 사용 .RespondBy(Method)과 확장 object.WhenSomethingChanges += new EventHandler(DoingThisOtherThing);

나는 인터넷 검색의 무리를했고, 나는하지 않았다 동안 정확히 복잡한 세부 사항을 파악, 나는 이것이 당신이 로컬 필드 또는 공개 이벤트에 액세스하는지 여부와 관련이 있다는 것을 이해합니다.

그 말로는, "어떻게"할 수 있고, "왜"내 첫번째 시도가 효과가 없는지에 관심이 없다는 것에 관심이 있습니다. "당신은 지금, 전혀 ...이 작업을 수행 할 수 .는"해결 방법을 실패, 적어도 확실한 또한 유용한 정보가 될 것입니다 ...

Image of attempted usage, does not compile

CommuncationsStatusPresenter (Image)

CommuncationsStatusPresenter (코드)

using System; 
using InspectionStation.Models; 
using InspectionStation.Views; 
using MachineControl.OPC; 

namespace InspectionStation.Presenters 
{ 
    public class CommuncationsStatusPresenter 
    { 
     // Fields 
     private ICommunicationsModel m_model; 
     private ICommunicationsView m_view; 

     // Constructor 
     public CommuncationsStatusPresenter 
      (ICommunicationsModel p_model, ICommunicationsView p_view) 
     { 
      m_model = p_model; 
      m_view = p_view; 
      HookEvents(); 
     } 
     private void HookEvents() 
     { 
      m_model 
       .When_Communications_Pulses_Heartbeat 
       .RespondBy(Setting_the_state_of_an_Indicator); 
     } 

     // Eventhandler 
     void Setting_the_state_of_an_Indicator(Tag sender, EventArgs e) 
     { 
      bool State = sender.BooleanValue; 
      m_view.Set_Communications_Status_Indicator = State; 
     } 
    } 
} 

RespondBy

using System; 

namespace Common.Extensions 
{ 
    public static partial class ExtensionMethods 
    { 
     public static 
      void RespondBy<TSender, TEventArgs>(this 
      GenericEventHandler<TSender, TEventArgs> p_event, 
      GenericEventHandler<TSender, TEventArgs> p_handler 
      ) where TEventArgs : EventArgs 
     { 
      p_event += new GenericEventHandler<TSender, TEventArgs>(p_handler); 
     } 
    } 
} 

GenericEventHandler

using System; 

namespace Common 
{ 
    [SerializableAttribute] 
    public delegate void GenericEventHandler<TSender, TEventArgs> 
     (TSender sender, TEventArgs e) 
     where TEventArgs : EventArgs; 
} 

ICommunicationsModel

using System; 
using Common; 
using MachineControl.OPC; 

namespace InspectionStation.Models 
{ 
    public interface ICommunicationsModel 
    { 
     event GenericEventHandler<Tag, EventArgs> 
      When_Communications_Pulses_Heartbeat; 
    } 
} 

ICommunicationsView

C# 컴파일러가 엄격 이벤트가 += 또는 -=, 핸들러에 대한 연결 및 분리 명령 다음에 할 필요가있는 클래스 외부 를 사용하는 것이 필요하기 때문에
namespace InspectionStation.Views 
{ 
    public interface ICommunicationsView 
    { 
     bool Set_Communications_Status_Indicator { set; } 
    } 
} 

답변

1

, 확장이 외부를 사용할 수없는 클래스. 그러나

, 당신이 좋아하는 클래스 자체에 대한 구체적인 방법을 구축하고자하는 경우 : 클래스가 이벤트를 정의하기 때문에

object.RespondWhenSomethingChangesBy(DoingThisOtherThing); 

은 다음, 그 방법의 내부 확장 방법을 활용할 수있다. 나는 당신이 이벤트에 대한 보일러 플레이트 코드를 많이 구축 할 것을 의미 알고, 그러나 이것은 당신이 정말로 다음 원하는 경우 전술은보다 더 효율적인 것으로 판명 될 수 있습니다 내가 충분히 할

object.WhenSomethingChanges.RespondBy(DoingThisOtherThing); 

여기서 귀하의 위치를 ​​이해하고 Microsoft가 향후 이벤트 확장을 허용하기를 희망합니다. (필자가 사용하는 흥미로운 이유 중 일부는 생각할 수 있습니다.) 그러나 그때까지는 우리는 그 문제를 해결해야 할 것입니다.솔직히, 나는 매우 좋은 이유가 있다고 확신합니다. 처음에는 구현되지 않았기 때문에, Microsoft는 이러한 것들을 통해 생각해 보았습니다.

+0

글쎄, 그건 충분히 명확한 것 같습니다! 감사합니다 :) – HodlDwon

+0

흠 ... 이것은 잠재적으로 더 많은 노력보다 유망 보이지만 http://stackoverflow.com/questions/18385967/c-sharp-event-keyword-advantages 기본적으로 생각은 표준'이벤트'shortcircuit입니다 키워드 수식어를 사용하고 기꺼이 자유롭게 대리인/작업을 수동으로 전달할 수 있습니다. 나는이 구현을 시도하지 않았고 링크에 예제가 없다. 그러나 모든 부분이 원래의 질문에 가능한 해결책을 제시 할 수있는 것 같다. 나는이 질문을 어떤 시점에서 다시 살펴보고, 단지 킥을위한 것이라해도 나는 우아한 구현을 얻을 수 있는지 알아볼 것이다. – HodlDwon

1

을 감안할 때 Michael Perrenoud의 대답은, 나는 내 패턴의 일환으로 다음과 같은 일을 해결 ...

public class CommuncationsStatusPresenter 
    { 
     ... 

     private void HookEvents() 
     { 
      m_model. 
       When_Communications_Pulses_Heartbeat += new EventHandler<Tag, EventArgs>(
       Set_the_state_of_an_Indicator); 
     } 

     // Eventhandler 
     void Set_the_state_of_an_Indicator(Tag sender, EventArgs e) 
     { 
      ... 
     } 
    } 
} 

그것은 ... 자동차가-서식 신규 라인에 따라 단지 conistent, 아무것도 특별한 없습니다 만 보인다습니다 이 시점에서 가장 좋은 해결책이 될 수 있습니다 (즉, ).은 광범위한 설명에 의지하지 않고 코드의 의도를 신속하게 알아 내기 위해 큰 소리로 읽습니다.

는 : 특별한 이름을 많이 필요가 아니에요 나는 긴 GenericEventHandler 단순히 EventHandler 이름을 변경.