반사를 통해이 작업을 수행 할 수 있지만 명확하지 않습니다. 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가 더 이상 문제가되지 않기 때문에 실제적으로 이것이 완전한 신뢰로 제대로 작동하도록합니다.
제네릭 메서드는 이벤트를 속성으로 전달할 수 없으므로 "왼손에서만 발생해야합니다"등의 오류가 발생하는 문제가 발생합니다. 해결 방법은 이벤트 키워드를 제거하는 것입니다. 이벤트는 여전히 정상적으로 작동하지만 문제없이 돌아 다니며 일반적으로 제기됩니다. –
아, 아주 멋진 트릭 :) 나는 XXXEvent 필드에 대해 몰랐다. 자동으로 컴파일러에 의해 생성 된 것 같은가요? –
토마스 : 예. @ 가진 : 왜 당신은 속성으로 전달 된 이벤트가 필요합니까? 여기, 이름으로 이벤트를 사용하고 있습니다 ... –