gpt4 book ai didi

c# - 这是类层次结构的 "traditional"处置模式的合法替代方案吗?

转载 作者:行者123 更新时间:2023-11-30 20:13:41 24 4
gpt4 key购买 nike

我不喜欢样板代码:复制粘贴重用可能容易出错。即使您使用代码片段或智能模板,也不能保证其他开发人员做到了,这意味着不能保证他们做对了。而且,如果您必须查看代码,则必须理解和/或维护它。

我想从社区了解的是:我对类层次结构的 IDispose 的实现是否是 "traditional" dispose pattern 的合法替代方案? ?我所说的合法​​是指正确、性能合理、健壮且可维护。

我可以接受这个替代方案是完全错误的,但如果是这样,我想知道为什么。

此实现假定您可以完全控制类层次结构;如果你不这样做,你可能不得不求助于样板代码。对 Add*() 的调用通常在构造函数中进行。

public abstract class DisposableObject : IDisposable
{
protected DisposableObject()
{}

protected DisposableObject(Action managedDisposer)
{
AddDisposers(managedDisposer, null);
}

protected DisposableObject(Action managedDisposer, Action unmanagedDisposer)
{
AddDisposers(managedDisposer, unmanagedDisposer);
}

public bool IsDisposed
{
get { return disposeIndex == -1; }
}

public void CheckDisposed()
{
if (IsDisposed)
throw new ObjectDisposedException("This instance is disposed.");
}

protected void AddDisposers(Action managedDisposer, Action unmanagedDisposer)
{
managedDisposers.Add(managedDisposer);
unmanagedDisposers.Add(unmanagedDisposer);
disposeIndex++;
}

protected void AddManagedDisposer(Action managedDisposer)
{
AddDisposers(managedDisposer, null);
}

protected void AddUnmanagedDisposer(Action unmanagedDisposer)
{
AddDisposers(null, unmanagedDisposer);
}

public void Dispose()
{
if (disposeIndex != -1)
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

~DisposableObject()
{
if (disposeIndex != -1)
Dispose(false);
}

private void Dispose(bool disposing)
{
for (; disposeIndex != -1; --disposeIndex)
{
if (disposing)
if (managedDisposers[disposeIndex] != null)
managedDisposers[disposeIndex]();
if (unmanagedDisposers[disposeIndex] != null)
unmanagedDisposers[disposeIndex]();
}
}

private readonly IList<Action> managedDisposers = new List<Action>();
private readonly IList<Action> unmanagedDisposers = new List<Action>();
private int disposeIndex = -1;
}

从某种意义上说,这是一个“完整”的实现,我提供了对终结器的支持(知道大多数实现不需要终结器),检查对象是否被释放等。真正的实现可能会删除终结器,例如,或者创建包含终结器的 DisposableObject 的子类。基本上,我为这个问题投入了所有我能想到的东西。

我可能错过了一些边缘案例和深奥的情况,所以我邀请任何人在这种方法中找出漏洞或通过更正来支持它。

其他替代方案可能是在 DisposableObject 中使用单个 Queue 处置器 而不是两个列表;在这种情况下,当处理器被调用时,它们会从列表中移除。我能想到其他细微的变化,但它们具有相同的一般结果:没有样板代码。

最佳答案

您可能遇到的第一个问题是 C# 只允许您从单个基类继承,在这种情况下,基类将始终 DisposableObject。就在这里,您通过强制添加额外的层使您的类层次结构变得困惑,以便需要从 DisposableObject 和其他一些对象继承的类可以这样做。

在此实现过程中,您还引入了很多开销和维护问题(更不用说每次新人加入项目时的重复培训成本,您必须解释他们应该如何使用此实现而不是定义的模式)。您知道有多个状态可以跟踪您的两个列表,对操作的调用没有错误处理,调用操作时的语法看起来“很奇怪”(虽然从数组调用方法可能很常见,简单地将 () 放在数组访问之后的语法看起来很奇怪。

我理解减少必须编写的样板文件数量的愿望,但可处置性通常不是我建议走捷径或以其他方式偏离模式的领域之一。我通常得到的最接近的方法是使用一个辅助方法(或扩展方法)来包装对给定对象的 Dispose() 的实际调用。这些调用通常如下所示:

if (someObject != null)
{
someObject.Dispose();
}

这可以使用辅助方法进行简化,但请记住,FxCop(或检查正确处置实现的任何其他静态分析工具)会报错。

就性能而言,请记住您正在使用此类实现进行大量委托(delegate)调用。就委托(delegate)的性质而言,这比普通方法调用的成本要高一些。

可维护性在这里绝对是一个问题。正如我提到的,每次有新人加入项目时,您都会承担重复培训成本,并且您必须解释他们应该如何使用此实现而不是定义的模式。不仅如此,每个人都记得将他们的一次性元素添加到您的列表中,您会遇到问题。

总的来说,我认为这样做是个坏主意,会导致很多问题,尤其是随着项目和团队规模的增加。

关于c# - 这是类层次结构的 "traditional"处置模式的合法替代方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1397196/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com