Tuyên bố var events = GetType().GetEvents();
cho bạn danh sách EventInfo
đối tượng được liên kết với loại hiện tại, không phải là cá thể hiện tại. Vì vậy, đối tượng EventInfo
không chứa thông tin về cá thể hiện tại và do đó nó không biết về các đại biểu có dây.
Để nhận thông tin bạn muốn, bạn cần lấy trường sao lưu cho trình xử lý sự kiện trên phiên bản hiện tại của bạn. Đây là cách:
public class MyClass
{
public event EventHandler MyEvent;
public IEnumerable<MethodInfo> GetSubscribedMethods()
{
Func<EventInfo, FieldInfo> ei2fi =
ei => this.GetType().GetField(ei.Name,
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.GetField);
return from eventInfo in this.GetType().GetEvents()
let eventFieldInfo = ei2fi(eventInfo)
let eventFieldValue =
(System.Delegate)eventFieldInfo.GetValue(this)
from subscribedDelegate in eventFieldValue.GetInvocationList()
select subscribedDelegate.Method;
}
}
Bây giờ mã gọi của bạn có thể trông như thế này:
class GetSubscribedMethodsExample
{
public static void Execute()
{
var instance = new MyClass();
instance.MyEvent += new EventHandler(MyHandler);
instance.MyEvent += (s, e) => { };
instance.GetSubscribedMethods()
.Run(h => Console.WriteLine(h.Name));
}
static void MyHandler(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Sản lượng từ trên là:
MyHandler
<Execute>b__0
tôi chắc chắn rằng bạn có thể JIG xung quanh với mã nếu bạn muốn trả lại đại biểu thay vì thông tin về phương thức, v.v.
Tôi hy vọng điều này sẽ hữu ích.
Trích dẫn từ câu trả lời cao nhất bình chọn trên câu hỏi trước của bạn: "Bây giờ tôi giả sử bạn có thể thử để tìm ra cơ thể của 'add' xử lý, biên soạn lại nó và tìm ra cách xử lý sự kiện đang được lưu trữ, và lấy chúng theo cách đó ... ** nhưng xin đừng ** Bạn đang tạo ra rất nhiều công việc, chỉ để phá vỡ đóng gói. Chỉ cần ** thiết kế lại mã của bạn ** để bạn không cần phải làm cái này." Tôi hết lòng đồng ý. –