Có, nó sẽ hoạt động như bạn muốn.
So sánh không theo tham chiếu, nó là theo giá trị, có nghĩa là bạn có thể hủy đăng ký một đại biểu khác, miễn là nó trỏ đến cùng một phương thức trên cùng một đối tượng.
Nói cách khác, điều này sẽ chỉ làm việc tốt:
var delegate1 = new ExternalObjectClickEventHandler(MethodA);
var delegate2 = new ExternalObjectClickEventHandler(MethodA);
ExternalObject.Click += delegate1;
ExternalObject.Click -= delegate2;
phương pháp Anonymous đang khác nhau tuy nhiên, bạn không thể làm điều này:
public MethodB()
{
ExternalObject.Click +=() => { return 10; };
}
public MethodC()
{
ExternalObject.Click -=() => { return 10; };
}
Trong khi phương pháp chứa mã cùng, họ được coi khác nhau và do đó điều này sẽ không hoạt động, tức là, MethodC
sẽ không hủy đăng ký đại biểu bạn đã thêm trong MethodB
.
Để giải quyết vấn đề này, bạn phải lưu trữ các đại biểu giữa lời gọi, như thế này:
private ExternalObjectClickEventHandler _ClickEventHandler;
public MethodB()
{
_ClickEventHandler =() => { return 10; };
ExternalObject.Click += _ClickEventHandler;
}
public MethodC()
{
ExternalObject.Click -= _ClickEventHandler;
}
Nhưng mã bạn thấy, sẽ làm việc.
Đối với câu hỏi của bạn những gì xảy ra đằng sau hậu trường, đó là hai dòng mã sau đây là giống hệt nhau khi nói đến mã được tạo:
ExternalObject.Click += MethodA;
ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA);
Các mã thứ hai là những gì được tạo ra từ đầu tiên (giả sử loại sự kiện được hiển thị.)
Cú pháp đầu tiên là (tại một số điểm) được thêm vào là "đường cú pháp" được dịch bởi trình biên dịch như thể bạn đã viết cú pháp thứ hai. Lưu ý rằng điều này chỉ xảy ra nếu được biên dịch có thể tìm ra đúng loại 100%. Tôi đã nhìn thấy một số trường hợp (mà tôi không thể nhớ ngay bây giờ), nơi bạn đã phải sử dụng cú pháp đủ điều kiện bởi vì trình biên dịch không thể tìm ra những gì bạn có nghĩa là. Đặc biệt, phương pháp quá tải và generics có thể gây nhầm lẫn nó trong lĩnh vực này.
Cảm ơn bạn đã trả lời kỹ lưỡng. – kubal5003