属性或变量更改值时的Fire事件

我想为我所拥有的项目添加更多function,这些项目使用了.NET Framework中打包的许多类。 这些相同的类提供了许多属性,这些属性可以非常有用地适应我的项目的function,但是这些类缺少的一件事是事件。

如果每个属性都有一个适当的事件,只要这个属性的值发生变化就会触发,我可以根据这些属性值分配一个事件处理程序。

我制作了一个示例案例,以最简单的方式说明我的目标。

样例:

System.Net.Sockets.Socket类( MSDN Docs上的Socket )有一个名为Connected的属性,如果套接字连接到指定的端点,则基本上返回true,否则返回false。

我想要完成的事情很简单。 我希望将此属性保留在“监视”下,当它的值发生变化时,触发一个事件。

这样做对我自己的一个类来说很简单,虽然使用INotifyPropertyChanged接口有点令人讨厌,只是因为我的代码总是改变了我必须手动触发事件的属性值。 不幸的是,据我所知,甚至这种程序都不能应用于.NET Framework中分布的现有Socket类。

好吧,这个问题变得非常广泛,抱歉,但我希望它能够深入了解我的目标。

现在简单地说,我想观察Socket类的Connected属性,当它的值发生变化时,触发一个事件。 如果有可能也使用这种方法来观察变量以及属性,那将是非常棒的,不仅对我而言,对于每个在SO上遇到这个问题的人来说都是如此。

当然,首选一种简单轻量级的方法,但最重要的是,我想了解它是如何完成的,所以将来我可以将它大规模地应用到其他类中。

我意识到我问了很多。 非常感谢。

有问题请问。

我实现了一个基本类,可以帮助你入门。 我确信一个function齐全,生产就绪,线程安全的类需要更多的工作,而且你需要实现自己的策略来何时轮询值的变化。

 public class TargettedObserver { private static readonly EqualityComparer EqualityComparer = EqualityComparer.Default; private Func ValueTarget; private T OldValue; public event ObservedValueChangedEventHandler ValueChanged; public TargettedObserver(Func valueTarget) { this.ValueTarget = valueTarget; OldValue = ObtainCurrentValue(); } public bool CheckValue() { T oldValue = OldValue; T newValue = ObtainCurrentValue(); bool hasValueChanged = CompareValues(oldValue, newValue); if (hasValueChanged) { OldValue = newValue; NotifyValueChanged(oldValue, newValue); } return hasValueChanged; } private void NotifyValueChanged(T oldValue, T newValue) { var valueChangedEvent = ValueChanged; if (valueChangedEvent != null) valueChangedEvent(this, new ObservedValueChangedEventArgs(oldValue, newValue)); } private static bool CompareValues(T oldValue, T newValue) { return !EqualityComparer.Equals(oldValue, newValue); } private T ObtainCurrentValue() { return ValueTarget(); } } 

事件处理:

 public class ObservedValueChangedEventArgs : EventArgs { public T OldValue { get; private set; } public T NewValue { get; private set; } public ObservedValueChangedEventArgs(T oldValue, T newValue) { this.OldValue = oldValue; this.NewValue = newValue; } } public delegate void ObservedValueChangedEventHandler(TargettedObserver observer, ObservedValueChangedEventArgs eventArgs); 

用法看起来像这样:

 public class TestClass { private Socket MySocket; private static TargettedObserver SocketConnectedObserver; public void Main() { MySocket = new Socket(); SocketConnectedObserver = new TargettedObserver(() => MySocket.Connected); SocketConnectedObserver.ValueChanged += ReportSocketConnectedStateChanged; PerformSocketConnection(); MainThread.Invoke(PollSocketValue); } private void PollSocketValue() { SocketConnectedObserver.CheckValue(); MainThread.Invoke(PollSocketValue); } private void ReportSocketConnectedStateChanged(TargettedObserver observer, ObservedValueChangedEventArgs eventArgs) { Console.WriteLine("Socket connection state changed! OldValue: " + eventArgs.OldValue + ", NewValue: " + eventArgs.NewValue); } } 

请注意,构造函数采用一个简单的lambda表达式,可以计算您想要观察的值。

另请注意, MainThread.Invoke只是一个伪代码,用于显示轮询每个主线程循环的更改。 我确信有更好的策略(具有定时器间隔的后台线程),例如可以以漂亮,可重用的方式实现。 在取消注册观察员方面还有许多工作要做。 可能会创建一些漂亮的工厂方法或lambda委托,因此您不需要保持TargettedObserver实例浮动并减少布线/手动代码的数量。 但至少这应该是一个开始。

您正在寻找的是观察者模式的实现。 像Observable实现可能会起作用。

另请参见.NET 4中的IObserver接口 :

IObserverIObservable接口为基于推送的通知提供了通用机制。 IObservable接口表示发送通知的类(提供者); IObserver接口表示接收它们的类(观察者)。 T表示提供通知信息的类。