构造函数链中的 IDisposable
IDisposable within Constructor Chain
我有以下两个构造函数:
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
字段。我可以在每个构造函数中复制逻辑,但这显然不是一个好的解决方案。
我真的更愿意保留第二个构造函数提供的语法糖。我怎样才能最好地做到这一点?或者这只是个坏主意?
我不太确定是什么阻止你在采用 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();
}
}
}
看看 StreamReader
实现,它有两种类型的 ctors:
public StreamReader(Stream stream)
: this(stream, true)
{
}
public StreamReader(string path)
: this(path, true)
{
}
在内部,它们都使用参数 leaveOpen
调用相同的 Init
方法,第一个 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();
}
}
}
我有以下两个构造函数:
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
字段。我可以在每个构造函数中复制逻辑,但这显然不是一个好的解决方案。
我真的更愿意保留第二个构造函数提供的语法糖。我怎样才能最好地做到这一点?或者这只是个坏主意?
我不太确定是什么阻止你在采用 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();
}
}
}
看看 StreamReader
实现,它有两种类型的 ctors:
public StreamReader(Stream stream)
: this(stream, true)
{
}
public StreamReader(string path)
: this(path, true)
{
}
在内部,它们都使用参数 leaveOpen
调用相同的 Init
方法,第一个 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();
}
}
}