根据之前的一个问题,一个用户告诉我,我不应该公开。net event风格的API,除非绝对被迫:
如果你没有被强制这样做,不要使用c#风格的事件来创建API。
在这种情况下,我应该如何实现一个"事件",一个模型将以某种方式通知任何观察者它已经改变了?该事件预计只被调用一次。比如说,我的模型是一个Minecraft Block,我在这个模型上调用Destroy()
方法。Destroy()
方法应该向它的观察者广播该模型打算被销毁。观察者的例子将是一个控制器,然后将BlockDestroyed
通知发送到视图(我欣赏控制器可能是一个不必要的间接级别,但是做模型->控制器->视图比模型(可观察对象)->视图(观察者)容易得多)。
下面是我的代码,我打算将其更改为Rx样式-记住,Destroyed
将只在每个块中调用一次-并且可能存在其他事件,例如Damaged
, Activated
和TextureChanged
。
public class Block
{
public Block()
{
}
/// <summary>
/// Destroy the block.
/// </summary>
public void Destroy()
{
var msg = new BlockDestroyedMessage();
if (Destroyed != null)
Destroyed(this, msg);
}
public event EventHandler<BlockDestroyedMessage> Destroyed;
}
还请注意,我在网上看到的文档基本上是
- 应该避免
ISubject<T>
,因为它鼓励违反SRP(我同意) - 不要实现
IObservable<T>
(因为有太多的工厂方法来创建可观察对象)
我会这样做:
public class Block
{
public void Destroy()
{
if (_destroyed != null)
{
var msg = new BlockDestroyedMessage();
_destroyed.OnNext(msg);
_destroyed.OnCompleted();
_destroyed = null;
}
}
private Subject<BlockDestroyedMessage> _destroyed
= new Subject<BlockDestroyedMessage>();
public readonly IObservable<BlockDestroyedMessage> Destroyed
= _destroyed.AsObservable();
}