Tôi có lớp sau đây, trong đó có một sự kiện nào được gọi là LengthChanged
:Làm thế nào để tham khảo một sự kiện trong C#
class Dimension
{
public int Length
{
get
{
return this.length;
}
set
{
if (this.length != value)
{
this.length = value;
this.OnLengthChanged();
}
}
protected virtual void OnLengthChanged()
{
var handler = this.LengthChanged;
if (handler != null)
{
handler (this, System.EventArgs.Empty);
}
}
public event System.EventHandler LengthChanged;
private int length;
}
Tôi muốn để có thể đăng ký/xử lý unregister cho sự kiện này trong một phương pháp gọi là Observer
, không biết gì về lớp Dimension
. Tôi đã đưa ra hai kịch bản, không ai trong số đó là thực sự thỏa mãn:
Xác định một giao diện
ILengthChanged
với sự kiệnLengthChanged
, thì chắc chắn rằngDimension
thực hiệnILengthChanged
. Sau đó, tôi phải cung cấp một triển khai phương phápObserver
cho mọi giao diện mà tôi xác định. Điều này bằng cách không có cách nào đủ chung chung. Tôi thực sự muốn có thể chỉ đơn giản là vượt qua trong một tham chiếu đến một sự kiệnSystem.EventHandler
.Sử dụng
System.Action<System.EventHandler>
callbacks đăng ký và unregistering xử lý sự kiện trong phương phápObserver
, chỉ cần như thế:lớp Foo { public void Observer (System.Action đăng ký, System.Action unregister) { đăng ký (this.MyEventHandler);
// keep track of the unregister callback, so that we can unregister // our event handler later on, if needed... } private void MyEventHandler(object sender, System.EventArgs e) { ... }
}
mà sau đó sẽ được gọi như thế này:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
và trong đó, khi thực hiện, thực sự sẽ kết thúc dây sự kiện LengthChanged
với xử lý sự kiện nội bộ MyEventHandler
. Nhưng điều này không phải là rất thanh lịch. Tôi rất muốn có thể viết thay thế này:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
nhưng tôi không biết làm thế nào để đạt được điều này. Có lẽ tôi đang thiếu một cái gì đó thực sự rõ ràng ở đây? Tôi đoán rằng một số ma thuật dynamic
có thể làm thủ thuật, bằng cách nào đó, nhưng điều này sẽ không thực thi kiểm tra kiểu biên dịch: Tôi không muốn người dùng của Observer
chuyển các tham chiếu đến các sự kiện không đáp ứng chữ ký sự kiện System.EventHandler
.
Nếu những người như Erik Meijer đã không thể đưa ra các giải pháp sạch hơn, tôi nghi ngờ rằng thực sự, không có cách nào khác để làm điều đó. Thật buồn ... Cảm ơn bạn đã trả lời nhanh chóng, Jon. –