2009-08-04 3 views
3
public class a 
{ 
    public event eventhandler test; 
    public void RaiseTest(){//fire test} 
} 

메소드를 호출하지 않고이 클래스 외부에서이 클래스에 대한 테스트를 수행 할 수 있습니까?사용자 정의 함수없이 해당 객체 외부에서 객체에 이벤트를 발생시킬 수 있습니까?

기본적으로 나는 외부 소스를 기반으로 제기해야하는 많은 수의 이벤트가 있으며 각 이벤트에 대해 Raise() 함수를 생성하고 싶지 않습니다.

이벤트를 매개 변수로 사용하도록 허용하는 일반적인 Raise()를 만들 수 있습니까? 그러므로 여전히 수업 내에서 호출 될 것입니다.

답변

4

반사를 통해이 작업을 수행 할 수 있지만 명확하지 않습니다. C#에서 이벤트를 선언하면 이벤트 이름이 "Event"인 클래스에 필드가 추가됩니다. 필드에서 GetValue를 호출하면 MulticastDelegate 인스턴스가 반환됩니다.

당신이 MulticastDelegate이 있으면, 당신은 호출 목록을 가져, 각 차례로 멤버 호출 할 수 있습니다 :이 인스턴스에서 비공개 필드를 받고 필요로

EventArgs e = new EventArgs(myClassInstance); // Create appropriate EventArgs 

MulticastDelegate eventDelagate = 
    this.GetType().GetField(theEventName + "Event", 
    System.Reflection.BindingFlags.Instance | 
    System.Reflection.BindingFlags.NonPublic).GetValue(myClassInstance) as MulticastDelegate; 

Delegate[] delegates = eventDelagate.GetInvocationList(); 
foreach (Delegate del in delegates) { 
     del.Method.Invoke(del.Target, new object[] { myClassInstance, e }); 
} 

주, 그래서 그것은 단지 전체에서 작동합니다 신뢰하고 매우 제한적입니다.

이벤트를 매개 변수로 사용하는 일반 Raise()를 만들 수 있습니까? 그러므로 여전히 수업 내에서 호출 될 것입니다.

예. 이렇게하려면 위의 코드를 수정하는 것이 매우 쉽습니다. 그냥 "myClassInstance"를이 값으로 대체하십시오. 이것은 NonPublic BindingFlag가 더 이상 문제가되지 않기 때문에 실제적으로 이것이 완전한 신뢰로 제대로 작동하도록합니다.

+0

제네릭 메서드는 이벤트를 속성으로 전달할 수 없으므로 "왼손에서만 발생해야합니다"등의 오류가 발생하는 문제가 발생합니다. 해결 방법은 이벤트 키워드를 제거하는 것입니다. 이벤트는 여전히 정상적으로 작동하지만 문제없이 돌아 다니며 일반적으로 제기됩니다. –

+0

아, 아주 멋진 트릭 :) 나는 XXXEvent 필드에 대해 몰랐다. 자동으로 컴파일러에 의해 생성 된 것 같은가요? –

+0

토마스 : 예. @ 가진 : 왜 당신은 속성으로 전달 된 이벤트가 필요합니까? 여기, 이름으로 이벤트를 사용하고 있습니다 ... –

2

메서드를 호출하지 않고이 클래스 외부에서이 클래스에 대한 테스트를 수행 할 수 있습니까?

짧은 대답 : 아니오.

만 이벤트를 선언하는 클래스는

가 매개 변수로 제기 할 수있는 이벤트를 받아들이는 일반적인 올립니다()을 만들 수 있습니다 올릴 수 있습니까? 그러므로 여전히 수업 내에서 호출 될 것입니다.

저는 그렇게 생각하지 않습니다. 적어도 쉽게 ... 반사를 사용하더라도, EventInfo.Invoke 방법이 없습니다. AFAIK, 이벤트를 발생시키는 유일한 방법은 클래스 내에서 정적입니다.

EDIT : 실제로 수행 할 수 있습니다 (리드의 답변 참조). 그러나 앱이 완전히 신뢰하에 실행되어야한다는 제한이 있습니다.

+0

토마스 : 리플렉션을 통해 이것을 처리하는 방법에 대한 내 대답을 참조하십시오. 완전히 신뢰하면 수업의 외부에서도 실제로 할 수 있습니다. 부분 신뢰에서는 이벤트 이름을 매개 변수로 사용하는 메서드로이를 호출하도록 설정할 수 있습니다. –