Summary: if I create an object in a constructor initialiser, how do I keep a reference to it so I can reference it later?
Details:
I have a class (LibBase, below) that requires a StreamWriter as its construction parameter. I don’t have the source code for LibBase – its in a third-party library.
public class LibBase
{
public LibBase(System.IO.StreamWriter wtr) { ... }
}
I have derived MyClass from LibBase and in the MyClass constructor I want to pass an instance of MyWriter (derived form StreamWriter) to the base class. I do this as follows.
public class MyWriter : System.IO.StreamWriter
{
public MyWriter(int n) { ... }
// Contains unmanaged resources
}
public class MyClass : LibBase
{
public MyClass(int n)
: LibBase(new MyWriter(n))
{ }
}
The problem is that MyWriter requires disposing, so MyClass should dispose it (and implement IDisposable to do this) but MyClass doesn’t have a reference to the created MyWriter instance, so I can’t dispose it. The syntax for the constructor initialiser doesn’t seem to permit my to keep a reference.
My solution is to re-code MyClass as follows:
public class MyClass : LibBase, IDisposable
{
public MyClass(Encoding enc)
: this(new MyWriter(enc))
{ }
private MyClass(MyWriter wtr)
: LibBase(wtr)
{ this.wtr = wtr; } // store reference
private MyWriter wtr;
// (implement IDisposable using wtr member variable
}
The private constructor stores a reference to the MyWriter instance so I can dispose it later.
My questions:
- What am I missing here? I feel like I’m fighting the language. Does C# provide a better way to do this?
- If the language doesn’t directly support this, is there a better solution than my private constructor technique?
- Any comments on defects in my solution?
Your solution seems ok… I don’t think that you miss anything…
IF you want to change the implementation (for whatever reason):
LibBasebut having an instance as a private member…MyClassthus having no public constructor and creating theStreamWriterinstance factory-side etc.BUT as I said there is nothing wrong with you solution (if it happens often you probably should rethink your design).
EDIT – as per comment:
What I mean by “creating StreamWriter factory-side” is: create a Factory for
MyClassso that anyone needing an instance uses the Factory… therein you can create theStreamWriterinstance in the Factory method and pass it in as param toMyClass… this way you could even implement some fancy things like “whichMyClassinstance is using a givenStreamWriterinstance ?” or some sort of a cache forMyClass/StreamWriterinstances etc.