与此问题类似,我希望将IDisposable用于其他设计之外的其他内容.
这个应用程序并不是非常相关,但仅仅是一个很好的例子:我有一个Windows Forms应用程序,我实现了一个Undo设计模式.通常,这是通过拦截UI元素中的"Value Changed"事件来完成的.对于DataGridView,CellEndEdit等等.但是在某些情况下,我会以编程方式更改数据,并且我希望每个撤消操作都跟踪它们,而不跟踪它们.
我有办法完成所有这些,但我在计算中管理我的"我应该撤消"逻辑:
private int _undoOverrides = 0;
public bool ShouldUndo { get { return _undoOverrides < 1; } }
public void DoNotUndo() { ++_undoOverrides; }
public void ResumeUndo() { --_undoOverrides; }
Run Code Online (Sandbox Code Playgroud)
现在,这种方法运行良好,但您必须记住ResumeUndo()在这样的业务逻辑结束时调用DoNotUndo().我想:
也许我不是太愚蠢的搞砸了,但是如果我不得不在代码中公开这个接口我会传递下去呢?如果可能的话,我想编译器可以为我处理这个问题.
我正在考虑使用一个实现IDisposable此类的类.这样,我的代码的用户可以使用一个using块,从不担心家务杂务.这是我到目前为止:
private static int _refCount = 0;
public static int ReferenceCount { get { return _refCount; } }
class HallPass : IDisposable
{
protected bool bActive;
public HallPass()
{
++Program._refCount;
bActive = true;
Console.WriteLine("Acquired hallpass!");
}
public void Dispose()
{
if (bActive)
--Program._refCount;
bActive = false;
Console.WriteLine("Hallpass expired!");
}
}
Run Code Online (Sandbox Code Playgroud)
我包含了一个布尔值,所以我确信我不会重复计算Dispose().所以你要做的HallPass就是:
using (new HallPass())
{
// do things...
}
Run Code Online (Sandbox Code Playgroud)
这是一个好主意吗?为什么这可能是一个坏主意?我应该知道的任何陷阱?
而且,我觉得这很愚蠢,但我很确定引用计数不适合它.它就像一个引用计数,但没有提及管理或内存来释放.编辑:可能是,现在不是.
它就像一个互斥体或一个关键部分,因为你试图throw在一段代码中对一个规则做出异常(另一个用词不当,因为我并不是那种意思),但它不是那些,因为它们'意味着在范围内相互排斥 - 如果您愿意,这可以以嵌套方式完成.这就是为什么它是一个计数,而不是一个布尔值.
我的第一个问题是Program._refCount可以从多个线程访问并且它没有被同步。但您可以说您的应用程序是单线程的。
下一个也是更大的问题是您没有真正按照应有的方式使用一次性图案。我个人认为,以应有的方式使用模式很重要,特别是当您不是唯一处理代码的人时。
ResumeUndo()现在您需要记住您必须打电话,而不是记住打电话Dispose()。问题是:您的团队成员会自然地意识到他们Dispose ()想要使用时需要打电话HallPass吗?(using语句很好,但它不能在所有场景中使用。如果有一个HallPasswho 的生存时间比单个方法的范围长,则不能将其包装在using语句中)Dispose()on是不好IDisposible的,但它通常不会影响程序的正确性 - 是的,你的程序会出现性能问题、泄漏等,但从功能上来说它通常仍然是正确的。但是对于您来说HallPass,如果有人忘记打电话Dispose(),我想将会出现功能错误。而且这个 bug 很难追踪。| 归档时间: |
|
| 查看次数: |
916 次 |
| 最近记录: |