具有复杂逻辑的多个构造函数

时间:2008-09-20 23:06:49

标签: c# .net

在C#中,如果你有多个构造函数,你可以这样做:

public MyClass(Guid inputId, string inputName){
    // do something
}

public MyClass(Guid inputId): this(inputId, "foo") {}

这个想法当然是代码重用。但是,当需要一些复杂的逻辑时,最好的方法是什么?说我想要这个构造函数:

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
 }

需要注意的是,我需要创建一个具有的对象,以便在使用后进行处置。 (澄清:不是立即,但我必须调用Dispose()而不是等待垃圾收集)

但是,如果我在重载的构造函数中添加一些代码,我没有看到再次调用基础构造函数的方法。有没有办法从一个重载的内部调用基础构造函数?

或者是否可以使用

public MyClass(MyOtherClass inputObject): this(inputObject.ID,
                                               inputObject.CreateHelper().Text) 
{}

这是否会自动从CreateHelper()生成对象?

编辑:到目前为止,谢谢。两个问题:我不控制MyOtherClass,我没有扩展方法(只有.NET 3.0 ......)。我确实控制了自己的类,因为我刚刚开始编写它,如果有一个好的方法,我没有问题重构构造函数。

3 个答案:

答案 0 :(得分:17)

用于解决此问题的最常见模式是使用构造函数调用的Initialize()方法,但在您刚刚给出的示例中,添加一个您调用的静态方法,就像下面的代码一样,可以解决这个问题。

public MyClass(MyOtherClass inputObject): this(inputObject.ID, GetHelperText(inputObject) {}

private static string GetHelperText(MyOtherClass o)
{
   using (var helper = o.CreateHelper())
      return helper.Text;
}

答案 1 :(得分:2)

我认为没有理由相信在构造函数中创建对象会自动处理该对象。是的,您的对象将立即超出范围并可用于垃圾收集,但这肯定与处置不同。

确实没有一种很好的方法可以完成您想要做的事情,但整个事情感觉它可以从一些重构中受益。当我发现自己试图向后弯曲以创建构造函数重载时,通常就是我自己的代码中的情况。

如果您可以控制MyOtherClass,为什么不通过添加处理dispose的getter方法来简化对该text属性的访问:

public class MyOtherClass
{
     //...
     public string GetText()
     {
        using (var h = CreateHelper())
             return h.Text;
     }
}

如果你不控制MyOtherClass,你可以使用扩展方法

public static class MyOtherClassExtensions
{
    public static string GetText(this MyOtherClass parent)
    {
        using(var helper = parent.CreateHelper())
        {
           return helper.Text;
        }
    }
}

然后,当然,在您的构造函数中,您可以安全地调用

public MyClass(MyOtherClass inputObject): this(inputObject.ID, inputObject.GetText()) {}

答案 2 :(得分:1)

只有在垃圾收集运行时才会自动处理该对象。如果您希望dispose在超出范围后立即运行,则应使用using块:

using (MyThirdClass mc = inputObject.CreateHelper())
{
  // do something with mc
}

这更像是一个风格问题,而不是你所拥有的问题的核心。