具有复杂逻辑的多个构造函数
在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 ...)。不过,我确实控制着我自己的类,并且由于我才刚刚开始编写它,所以如果有一个好的方法,我就可以毫无问题地重构构造函数。
解决方案
该对象仅在运行垃圾收集时自动处置。如果我们希望处理程序在超出范围后立即运行,则应使用using
块:
using (MyThirdClass mc = inputObject.CreateHelper()) { // do something with mc }
这实际上更多是与样式有关的问题,而不是我们所遇到问题的中心。
解决此问题的最常见模式是构造函数调用一个Initialize()方法,但是在我们刚才给出的示例中,添加一个调用的静态方法(如下面的代码)可以解决问题。
public MyClass(MyOtherClass inputObject): this(inputObject.ID, GetHelperText(inputObject) {} private static string GetHelperText(MyOtherClass o) { using (var helper = o.CreateHelper()) return helper.Text; }
我看不出有任何理由相信在构造函数中创建对象会自动处理该对象。是的,对象将立即超出范围,可用于垃圾回收,但是肯定与处置对象不同。
确实没有一种很好的方法可以完全执行我们想做的事情,但是整个过程似乎可以从某些重构中受益。当我发现自己试图向后弯腰以创建构造函数重载时,在我自己的代码中通常就是这种情况。
如果我们可以控制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()) {}