作为库程序集的一部分,我有一个抽象类SignalGenerator
,它实现了IDisposable
并具有多个子类。在此抽象类中,我维护每个单例子类的静态实例:
private static volatile Lazy<SignalGenerator> s_signalGenerator; // Default object instance if subclass not specified.
private static volatile Lazy<SignalGenerator> s_signalGeneratorSimulated;
private static volatile Lazy<SignalGenerator> s_signalGenerator79C3;
private static volatile Lazy<SignalGenerator> s_signalGenerator75C3;
private static volatile Lazy<SignalGenerator> s_signalGenerator41620;
我有一个单独的程序集,该程序集引用了该程序集并通过调用静态SignalGenerator.GetInstance(className)
方法来创建子类实例,该方法基于className
参数实例化上述类变量之一。
现在的问题是,在调用抽象类的Dispose()
方法时,要处理哪个子类:
using SignalGenerator s = SignalGenerator.GetInstance(nameof(P41620)); // P41620 is a subclass of SignalGenerator and corresponds to s_signalGenerator41620.
s.Dispose(); // How to tell abstract class which subclass to dispose of when Dispose doesn’t accept parameters?
我以为可以通过将以下方法添加到抽象类并在子类中覆盖它来解决这个问题:
protected virtual void Dispose(bool disposing, [CallerFilePath] string subclassName = "")
可以解析CallerFilePath
以找到调用子类的名称。但这仅在子类覆盖此Dispose方法的情况下起作用,而并非所有方法都起作用。
我意识到整个过程都有一点代码味道,所以我正在寻找更好的解决方案。
查看此MSDN source document,其中包含此非常重要的问题的详细信息。突出的几件事是:
...和本节:
The Dispose()方法
“因为类型的使用者调用了公共的,非虚拟的(在Visual Basic中为NonInheritable)无参数的Dispose方法,其目的是释放非托管资源,执行常规清理并指示终结器(如果有的话)。存在,不必运行。释放与托管对象相关的实际内存始终是垃圾收集器的工作范围。”
我的看法是,即使我们正在实现自己的IDispose模式,GC也会很好地照顾这一问题的虚拟化。就此类问题而言,据我所知。