Tôi gặp phải một tình huống mà tôi cần phải giải quyết một số nội bộ là Delegate
nhưng tôi muốn có một ràng buộc chung. Cụ thể, tôi muốn thêm một trình xử lý sự kiện bằng cách sử dụng sự phản chiếu, nhưng tôi muốn sử dụng một đối số chung cho đại biểu. Đoạn code dưới đây không làm việc, kể từ khi "Handler" là một loại biến, và trình biên dịch sẽ không đúc Handler
-Delegate
:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
Tuy nhiên, bạn có thể vượt qua một chức năng mà không được chuyển đổi cho bạn. convert
nhận một đối số Handler
và trả về một Delegate
:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
Bây giờ trình biên dịch là hạnh phúc. Gọi phương thức dễ dàng. Ví dụ, gắn với sự kiện KeyPress
trên Windows Forms điều khiển:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
nơi SomeControl_KeyPress
là mục tiêu của sự kiện. Điều quan trọng là lambda chuyển đổi - nó không hoạt động, nhưng nó thuyết phục trình biên dịch bạn đã cho nó một đại biểu hợp lệ.
(Bắt đầu 280Z28) @Justin: Tại sao không sử dụng?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(End 280Z28)
+1 cho: 1) bằng cách sử dụng hàm tạo tĩnh và 2) bao gồm thông báo chi tiết do điều kiện gỡ lỗi lạ xung quanh loại khởi tạo. –
@MarcGravell: Không ném ngoại lệ trong trình khởi tạo tĩnh vi phạm 'CA1065: Không tăng ngoại lệ ở các vị trí không mong muốn' ... Tôi luôn luôn giả định rằng bạn nên sử dụng quy tắc phân tích mã tùy chỉnh để tìm cách sử dụng không hợp lệ của lớp thường không có sẵn trong thời gian chạy. –