我有以下两个构造函数:
public Source(FileStream fileStream) {
// Stuff
}
public Source(String fileName) : this(new FileStream(fileName, FileMode.Open)) {
// Nothing, the other constructor does the work
}
第二个构造函数的问题很明显,正在创建和使用FileStream,但并未处理。因为它在构造函数链的内部,所以无法使用using
块。我无法将new FileStream()
移到构造函数的主体中,因为尽管它随后将位于using
块中,但无法调用其他构造函数的逻辑。我无法提取该逻辑,因为它修改了readonly
字段。我可以在每个构造函数中复制逻辑,但这显然不是一个好的解决方案。
我真的更希望保留第二个构造函数提供的语法糖。我怎样才能最好地做到这一点?还是这只是一个坏主意?
答案 0 :(得分:4)
我不太确定是什么阻止您在采用FileStream
的构造函数中对其进行处理:
public Source(FileStream fileStream) {
try
{
// Stuff
}
finally
{
fileStream.Dispose();
}
}
public Source(String fileName) : this(new FileStream(fileName, FileMode.Open)) {
// Nothing, the other constructor does the work
}
如果是因为您想让Stream
构造函数的调用者保持FileStream
有效,则可以添加第三个private
构造函数:
public Source(FileStream fileStream): this(fileStream, disposeStream: false) {
// Nothing, the other constructor does the work
}
public Source(String fileName) : this(new FileStream(fileName, FileMode.Open), disposeStream: true) {
// Nothing, the other constructor does the work
}
private Source(FileStream fileStream, bool disposeStream) {
try
{
// Stuff
}
finally
{
if (disposeStream)
{
fileStream.Dispose();
}
}
}
答案 1 :(得分:4)
看看StreamReader
的实现,它有两种类型的ctor:
public StreamReader(Stream stream)
: this(stream, true)
{
}
public StreamReader(string path)
: this(path, true)
{
}
内部都使用参数Init
调用相同的leaveOpen
方法,第一个ctor的参数设置为true
,第二个ctor的参数设置为false
对此参数Stream
进行处置(或不进行处置)。
因此您可以执行以下操作:
public class Source : IDisposable
{
private readonly Stream _stream;
private readonly bool _leaveOpen;
private Source(Stream stream, bool leaveOpen)
{
_stream = stream;
_leaveOpen = leaveOpen;
}
public Source(FileStream fileStream) : this(fileStream, true)
{
}
public Source(string fileName) : this(new FileStream(fileName, FileMode.Open), false)
{
}
public void Dispose()
{
if (!_leaveOpen)
{
_stream?.Dispose();
}
}
}