Mat*_*ght 6 c# constructor idisposable
我有一个小的对象层次结构,通常从a中的数据构造Stream,但对于某些特定的子类,可以从更简单的参数列表合成.在从子类链接构造函数时,我遇到了一个问题,即确保处理基类构造函数所需的合成流.它没有逃过我,以IDisposable这种方式使用对象可能只是脏池(plz建议?),原因我没有考虑过,但是,除了这个问题,它似乎相当简单(和良好的封装).
代码:
abstract class Node {
protected Node (Stream raw)
{
// calculate/generate some base class properties
}
}
class FilesystemNode : Node {
public FilesystemNode (FileStream fs)
: base (fs)
{
// all good here; disposing of fs not our responsibility
}
}
class CompositeNode : Node {
public CompositeNode (IEnumerable some_stuff)
: base (GenerateRaw (some_stuff))
{
// rogue stream from GenerateRaw now loose in the wild!
}
static Stream GenerateRaw (IEnumerable some_stuff)
{
var content = new MemoryStream ();
// molest elements of some_stuff into proper format, write to stream
content.Seek (0, SeekOrigin.Begin);
return content;
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到不处理a MemoryStream并不是一个世界性的CLR公民身份不好的情况,但它仍然给了我heebie-jeebies(更不用说我可能并不总是使用MemoryStream其他的亚型).它不在范围内,所以我不能Dispose ()在后面的构造函数中显式地显示它,并且添加一个using语句GenerateRaw ()是弄巧成拙的,因为我需要返回流.
有一个更好的方法吗?
先发制人的罢工:
Node构造函数中计算的属性应该是基类的一部分,不应该由子类计算(或可以在子类中访问)GenerateRaw ()的using语句中CompositeNode.但重复要求调用每个构造函数并且不能保证它为每个子类型运行(a Node不是a Node,在语义上,没有初始化这些属性)给了我heebie-jeebies比(潜在)资源更糟糕泄漏在这里.CompositeNode创建了流 -CompositeNode有责任,除非其他代码明确声明它将承担这一责任。这里的一种选择是基构造函数通过受保护的重载来允许这样做,但顺序意味着很难确切地知道何时可以安全地处置它。方法virtual允许您执行此操作,但您不应该真正virtual在构造函数中调用方法。
我想知道重构是否有一个initialize ( Load)方法(您在构造时单独调用)会更好。也许是一个protected virtual方法,并通过方法公开它public static。