2011-09-06 3 views
0

프로그램의 유연성을 고려하여 프로그램의 목적이 변경되었음을 감안할 때 현재 구축 중입니다. 기존 클래스가 구현할 인터페이스를 추가하고 싶습니다. 다음과 같이이벤트 핸들러, 새로운 인터페이스에 대한 기존 클래스

기존 클래스

public class ClassA 
{ 
    #region Events 
    public delegate void DataReceivedHandler(object sender, EventArgs e); 
    public delegate void DataSentHandler(object sender, EventArgs e); 
    public delegate void StatusUpdatedHandler(object sender, EventArgs e); 
    public event DataReceivedHandler DataReceived; 
    public event DataSentHandler DataSent; 
    public event StatusUpdatedHandler StatusUpdated; 
    #endregion 

    //rest of code here... 
} 

새 인터페이스

public interface IClassA 
{ 
    event EventHandler DataReceived; 
    event EventHandler DataSent; 
    event EventHandler StatusUpdated; 

    //rest of code here... 
} 

내 세 가지 질문이 있습니다.

Q1. 처음에 클래스에서 내 자신의 대리자를 선언 할 권리가 있습니까? 예 : public delegate void DataReceivedHandler 또는 이러한 이벤트를 제거하고 이벤트를 일반 EventHandler로 바꿔야합니다. 즉 public event EventHandler DataReceived입니다. 이러한 이벤트가 이벤트와 함께 데이터를 전달하지 않는다는 것을 감안할 때, 구독 한 항목에 무언가가 변경되었음을 알리는 것만으로 변경됩니다.

2. 위의 질문과 밀접하게 관련되어 있습니다. 클래스의 속성, 즉 status (StatusUpdated)를 변경하려고합니다. 새 상태를 사용자 지정 EventArgs로 전달하는 것이 가장 좋습니다. 따라서 원래 코드와 마찬가지로 사용자 지정 대리자가 필요합니까? 현재 작동하므로 이벤트가 시작되고 가입 ​​된 클래스는 발신자 값, 즉 (ClassA와 같은 발신자) 상태를 사용할 수 있습니다. 상태. 모범 사례가 있습니까 아니면 개발자에게 달려 있습니까?

3. 이제 그 일이 끝났습니다. 인터페이스에 관한 부분. 인터페이스에서 DataReceived 및 다른 이벤트를 올바르게 선언하여이를 구현으로 표시 할 클래스와 일치 시키십시오. 당신이 인터페이스 방법에 대한 사용자 정의 위임이 필요하면 그들이 특정 구현에 묶여 있지 않기 때문에, 당신은 (클래스 외부)을 개별적으로 선언해야

답변

1

. 델리게이트 선언은 클래스처럼 인터페이스 내부에있을 수 있습니다. 대리인 문제는 모두 (EventHandler)과 동일한 서명을 갖고 있으므로 중복됩니다.

이 이벤트를 발생시킬 때 데이터를 전달하지 않으면 일반 EventHandler 대리자를 사용할 수 있습니다. 그러나 DataReceived 이벤트로 일부 데이터를 얻을 것으로 예상되므로 의미가 있는지 확인하고 일부 데이터를 매개 변수로 허용하는 대리자를 사용해야합니다.

셋째, 사용자 인터페이스 이벤트 서명은 클래스의 서명이 일치해야합니다. 인터페이스에 EventHandler 대리자 형식을 사용할 수없고 클래스 내부의 서명을 변경할 수 없습니다.

대리자 형식을 명시 적으로 선언하지 않고 BCL과 함께 제공되는 일반 Action 대리자를 사용할 수도 있습니다 (.NET 3.5로 시작).

public interface IClassA 
{ 
    event Action<IClassA, Data> DataReceived; 
    event Action<IClassA, Data> DataSent; 
    event Action<IClassA, Status> StatusUpdated; 
} 

후자의 방법은 당신에게 (EventHandlerobject 반대) 강력한 형식의 sender 매개 변수를 갖는 혜택을 제공 :이 경우 당신이 뭔가를 할 수도 있습니다.질문에 대한 대답에서

+0

나는 당신과 Jamiecs을 두 가지 접근 방식을 시도하고 답변 주셔서 모두 감사했다. 나는 Action <>을 사용하는 것을 선호한다. GUI 호출에도 사용되는 것을 보았다. 익숙해지는 좋은 생각이다. 이 접근법에서 볼 수있는 유일한 단점은 자동 완성이 부족하다는 것입니다. 이전 이벤트에서 myClassA.StatusUpdated + = ....를 입력하면 + =는 자동으로 이벤트를 처리하는 메서드를 만듭니다 (사용자 정의 이벤트 args도 포함). 액션을 사용하면이 경우가 아니므로 직접 메소드를 작성해야합니다. – JonWillis

+0

선호도에 대한 또 다른 이유는 강력한 형식의 보낸 사람이지만 위임을 통해 얻을 수 있습니다. – JonWillis

+0

@Jon : 확실합니까? 위임자 서명 ('+ =', 타입'Tab'을 두 번 치고 메소드 스텁을 생성해야 함)에 관계없이 결코 그런 문제가 없었습니다. – Groo

1

, 이러한 의견의 문제입니다 물론 그래서 난 내주지 : 아니, 당신은 당신의 자신의 XXXHandler 대표를 다시 선언 할 권리 없음)

A1을, 하나가 프레임 워크 (EventHandler)가 정확히 일치합니다. "바퀴를 다시 발명했습니다."

A2) StatusChanged이라는 이벤트는 새로운 (잠재적으로 오래된) 상태를 모든 구독자에게 전달해야한다고 생각합니다. 그러나 이것은 프레임 워크가 정확히이 목적을 위해 일반 대리자 (EventHandler<TEventArgs>)를 정의하기 때문에 여전히 자신의 대리자를 구현할 이유가 아닙니다.

A3) 현재 클래스의 이벤트는 인터페이스와 일치하지 않으므로 변경하지 않고 구현할 수 없습니다.

문서는 : EventHandler<TEventArgs>

+0

Groo보다 간결한 대답이지만 Action <>을 사용하는 것이 좋습니다. 그의 대답에 대한 논평에서 하나의 단점 이외의. – JonWillis