Reputation: 180924
In C#, if you have multiple constructors, you can do something like this:
public MyClass(Guid inputId, string inputName){
// do something
}
public MyClass(Guid inputId): this(inputId, "foo") {}
The idea is of course code reuse. However, what is the best approach when there is a bit of complex logic needed? Say I want this constructor:
public MyClass(MyOtherClass inputObject)
{
Guid inputId = inputObject.ID;
MyThirdClass mc = inputObject.CreateHelper();
string inputText = mc.Text;
mc.Dispose();
// Need to call the main Constructor now with inputId and inputText
}
The caveat here is that I need to create an object that has to be disposed after use. (Clarification: Not immediately, but I have to call Dispose() rather than waiting for Garbage Collection)
However, I did not see a way to just call the base constructor again if I add some code inside my overloaded constructor. Is there a way to call the base constructor from within an overloaded one?
Or is it possible to use
public MyClass(MyOtherClass inputObject): this(inputObject.ID,
inputObject.CreateHelper().Text)
{}
Would this automatically Dispose the generated Object from CreateHelper()?
Edit: Thanks so far. Two problems: I do not control MyOtherClass and I do not have Extension Methods (only .NET 3.0...). I do control my own class though, and since I've just started writing it, I have no problem refactoring the constructors if there is a good approach.
Upvotes: 6
Views: 9023
Reputation: 135265
The object would only be automatically disposed when garbage collection runs. If you want the dispose to run as soon as it went out of scope, you should use a using
block:
using (MyThirdClass mc = inputObject.CreateHelper())
{
// do something with mc
}
This is really more of an issue with style and not really central to the question you had.
Upvotes: 1
Reputation: 12300
I don't see any reason to believe that creating an object in the constructor will automatically dispose the object. Yes, your object will immediately go out of scope and be available for garbage collection, but that is certainly not the same as being disposed.
There really isn't a great way to do exactly what you want to do, but the whole thing feels like it could benefit from some refactoring. That is usually the case in my own code when I find myself trying to bend over backwards to create a constructor overload.
If you have control over MyOtherClass, why not simplify the access to that text property by adding a getter method that handles the dispose:
public class MyOtherClass
{
//...
public string GetText()
{
using (var h = CreateHelper())
return h.Text;
}
}
if you don't control MyOtherClass you could use an extension method
public static class MyOtherClassExtensions
{
public static string GetText(this MyOtherClass parent)
{
using(var helper = parent.CreateHelper())
{
return helper.Text;
}
}
}
Then, of course, in your constructor you can safely call
public MyClass(MyOtherClass inputObject): this(inputObject.ID, inputObject.GetText()) {}
Upvotes: 2
Reputation: 4767
The most common pattern used to solve this problem is to have an Initialize() method that your constructors call, but in the example you just gave, adding a static method that you called like the code below, would do the trick.
public MyClass(MyOtherClass inputObject): this(inputObject.ID, GetHelperText(inputObject) {}
private static string GetHelperText(MyOtherClass o)
{
using (var helper = o.CreateHelper())
return helper.Text;
}
Upvotes: 17