ProgramingTip

동작

bestdevel 2020. 12. 11. 19:14
반응형

동작 대 델리게이트 이벤트


아래 코드를 상당히 번갈아 사용하는 개발자를 보았습니다. 이들 사이의 차이점은 무엇이며 표준에 따른 것은 무엇입니까? 로 그들은 동일 Action대리인 Func<T>아니라입니다 :

public event Action<EmployeeEventAgs> OnLeave;
public void Leave()
{
    OnLeave(new EmployeeEventAgs(this.ID));
}

VS

public delegate void GoOnLeave(EmployeeEventAgs e);
public event GoOnLeave OnLeave;
public void Leave()
{
    OnLeave(new EmployeeEventAgs(this.ID));
}

Fwiw, 두 예제 모두 표준 .NET 규칙을 사용하지 않습니다. EventHandler<T>일반적인 이벤트를 선언해야합니다 :

public event EventHandler<EmployeeEventArgs> Leave;

"On"접두사는 이벤트를 발생시키는 보호 된 메서드 용으로 예약되어야합니다.

protected virtual void OnLeave(EmployeeEventArgs e) {
    var handler = Leave;
    if (handler != null) handler(this, e);
}

은하지 않습니다 당신 , 괜찮아 식으로 할 것이 아니라, 사람은 즉시, 패턴을 인식 코드를 이해하고 사용 하고 사용자 정의하는 방법을 알 수 있습니다 .

그리고 사용자 지정 대리자 선언과 Action<>, 선택하도록 강요하지 않습니다 EventHandler<>. 귀하의 질문에 대답합니다.


다음 두 줄의 코드는 거의 동일합니다.

public event Action<EmployeeEventAgs> Leave;

비교 :

public event EventHandler<EmployeeEventAgs> Leave;

차이점은 이벤트 처리기 메서드의 서명에 있습니다. 작업에 첫 번째 접근 방식을 사용하는 경우 다음을 수행 할 수 있습니다.

public void LeaveHandler(EmployeeEventAgs e) { ... }

그리고 이것은 :

obj.Leave += LeaveHandler;

두 번째 접근 방식에서는 서명 LeaveHandler이 달라야합니다.

public void LeaveHandler(object sender, EmployeeEventAgs e) { ... }

이다 매우 중요 두 경우 모두에 다음과 같은 event키워드가 이벤트 멤버를 선언하는 데 사용됩니다. 이런 식으로 선언 된 이벤트 멤버는 마치있는 것처럼 보이지만 클래스의 필드가 아닙니다. 대신 컴파일러는이를 이벤트 속성 1 로 만듭니다 . 이벤트 속성은 get또는 set차별 점을 제외하면 일반 속성과 유사합니다 . 컴파일러에서는 +=-=할당 의에서만 사용할 수 있습니다 (이벤트 처리기 추가 또는 제거). 할당 된 이벤트 이미 핸들러덮어 쓰거나 이를 선언하는 클래스 외부에서 이벤트호출 할 수 있는 방법은 없습니다 .

두 예제에서 이벤트 키워드가 누락 된 경우 오류 또는 경고없이 다음 작업을 수행 할 수 있습니다.

obj.Leave = LeaveHandler;

이것은, 등록 된 것을 삭제 하고 가지 교체 LeaveHandler.

또한 다음 호출을 수행 할 수도 있습니다.

obj.Leave(new EmployeeEventAgs());

를 만들려는 이벤트 경우 위의 두 상황은 안티 패턴으로 간주됩니다 . 이벤트는 소유자 개체에 제거 만 호출되어야하며 구독자의 추적 할 수없는 제거를 허용 합니다. event키워드는 이벤트의 올바른 사용을 고수하는 데 도움이 .NET의 프로그래밍 구조입니다.

위의 내용을 염두에두고 키워드 없이는 EventHandler사용하지 EventHandler않을 가능성이 높기 때문에 많은 사람들이 접근 방식을 고수 생각 event합니다. 액션은 사용 범위가 더 넓으며 이벤트처럼 보이네요. 후자는 물론 개인적인 의견입니다. 이벤트 접근 방식이 제 자신의 코딩 관행에 너무 고정되어 있기입니다. 그럼에도 불구하고 행동이 확실한 사용 이벤트에 사용하는 범죄가 아닙니다.


1 이벤트 속성은 다음과 같은 코드를 볼 때 컴파일러가 자동으로 생성하는 것입니다.

event EventHandler SomeEvent 

다음과 같은 코드가됩니다.

private EventHandler _someEvent; // notice the lack of the event keyword!
public event EventHandler SomeEvent
{
    add { _someEvent += value; }
    remove { _someEvent -= value; }
}

다음과 같이 작성하는 이벤트 호출 :

this.SomeEvent(sender, args);

다음과 같이 변환됩니다.

this._someEvent(sender, args);

Action<T> 정확히 동일합니다 delegate void ... (T t)

Func<T> 정확히 동일합니다 delegate T ... ()


액션은 전체 델리게이트 선언의 지름길 일뿐입니다.

public delegate void Action<T>(T obj)

http://msdn.microsoft.com/en-us/library/018hxwa8.aspx

어느 것을 사용할지는 조직의 코딩 표준 / 스타일에 따라 다릅니다.


예, Action과 Func는 3.5 clr에 정의 된 단순한 편의 대리인입니다.

Action, Func 및 lambda는 모두 델리게이트를 사용하기위한 구문상의 설탕과 편의성입니다.

그들에게는 마법이 없습니다. 몇몇 사람들은이 기능을 2.0 코드에 추가하기 위해 간단한 2.0 애드온 라이브러리를 작성했습니다.


여기 에서 컴파일러가 실제로 Action에 대해 생성하는 것이 가장 좋은 설명인지 확인하는 것이 좋습니다. 작성한 내용에는 기능적 차이가 없으며 더 짧고 편리한 구문입니다.


일반적으로 동등합니다. 그러나 이벤트 유형에 대한 대리자를 사용하는 컨텍스트에서 규칙은 EventHandler를 사용하는 것입니다 (여기서 T는 EventArgs를 상속 함).

public event EventHandler<EmployeeEventArgs> Left;

public void Leave()
{
    OnLeft(this.ID);
}

protected virtual void OnLeft(int id)
{
    if (Left != null) {
        Left(new EmployeeEventArgs(id));
    }
}

이러한 Action 및 Func 제네릭 델리게이트를 직접 작성할 수도 있지만 일반적으로 유용하기 때문에 .Net 라이브러리에 갇혀 있습니다.

참고 URL : https://stackoverflow.com/questions/2282476/actiont-vs-delegate-event

반응형