tags:

views:

679

answers:

3

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 contructor:

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: 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 CreateGelper()?

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.

+1  A: 

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.

1800 INFORMATION
Since he said it *has* to be disposed after use, I took that to mean "immediately after use", in which case a using block would be necessary.
1800 INFORMATION
This does not really address the issue raised, that of how to perform a logical operation on a parameter and still fall through to another constructor using the contructor() : this() pattern.
spoon16
indeed. Sorry if i was unclear. My problem is that I need to get to my base constructor again with the data and that I have to dispose mc and not wait for garbage collection. Your and mine example are essentially the same, using and calling Dispose() Explicitely makes no difference for the question.
Michael Stum
Oh I agree, my answer was more a question of style. I wasn't really trying to give this as the correct answer to the original question. I voted up the answer by Stephan Rusek as being the best answer.
1800 INFORMATION
+14  A: 

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;
}
Stefan Rusek
That's a pretty clever approach, I think i'll add it to my book of best practices :) That'll work.
Michael Stum
I agree on the initialize method being the most common pattern. I think that is more consistent with the framework.
spoon16
If I could give you a triple-quadruple vote up, I would...
TonyOssa
Glad to help. :)
Stefan Rusek
@Stefan Rusek: boy would I hate to debug anything that comes out of that! +1 for being clever though.
sixlettervariables
+2  A: 

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()) {}
Nathan
Thanks. I can not use either due to 2 constraints i've just added to the question, but +1 for your answer.
Michael Stum