1

给定下面的两个类,我想用 int 参数调用 Child 构造函数,然后用 int 参数调用父构造函数,最后调用 Child 无参数构造函数。

这可以在不使用可选参数的情况下完成吗?

public class Parent
{
    public Parent()
    {
        Console.WriteLine("Parent ctor()");
    }

    public Parent(int i)
    {
        Console.WriteLine("Parent ctor(int)");
    }
}

public class Child:Parent
{
    public Child()
    {
        Console.WriteLine("Child ctor()");
    }

    public Child(int i)
    {
        Console.WriteLine("Child ctor(int)");
    }
}

这是我们希望在 .NET 2.0 中完成的 .NET 4 中的逻辑

public class Parent2
{
    public Parent2(int? i = null)
    {
        Console.WriteLine("Parent2 ctor()");

        if (i != null)
        {
            Console.WriteLine("Parent2 ctor(int)");

        }
    }
}

public class Child2 : Parent2
{
    public Child2(int? i = null)
        : base(i)
    {
        Console.WriteLine("Child2 ctor()");

        if (i != null)
        {
            Console.WriteLine("Child2 ctor(int)");
        }
    }
}

这是我们正在讨论的生产代码

public class DataPoint<T>
{
    public DataPoint() { }

    public DataPoint(T xValue, int yValue)
    {
        XAxis = xValue;
        YAxis = yValue;
    }

    public T XAxis { get; set; }
    public int YAxis { get; set; }
}

public class DataPointCollection<T> : DataPoint<T>
{
    DataPointCollection()
    {
        Labels = new List<string>();
    }

    DataPointCollection(T xValue, int yValue)
        : base(xValue, yValue)
    { }

    public List<string> Labels { get; set; }
}

编辑:

在这一点上,问题的原因是“代码高尔夫”学术练习,以最少的代码遵循 DRY 方法。正常模式是在类中使用内部私有函数,该函数具有要从每个构造函数执行的公共代码。

编辑 2

我添加了示例生产代码。

4

5 回答 5

2

不,你不能这样做,因为你不能ChildParent.

于 2012-07-27T18:15:01.080 回答
1

如果您需要一系列初始化方法,我建议您将它们定义为普通(不是构造函数)方法。您可以使用可覆盖的受保护方法来设置来回,因为构造函数可以选择以任意组合或顺序调用哪些初始化方法:

public class Parent {

    public Parent() { }

    public Parent(int i) {
        initWithArg(i);
        initNoArgs();
    }

    virtual protected void initWithArg(int i) {
        Console.WriteLine("Parent initWithArg(int)");
    }

    virtual protected void initNoArgs() {
        Console.WriteLine("Parent initNoArgs");
    }
}

public class Child : Parent {

    // Override the *parameterless* constructor
    public Child(int i) : base() {
        initWithArg(i);
        base.initWithArg(i);
        initNoArgs();
    }

    override protected void initWithArg(int i) {
        Console.WriteLine("Child initWithArg(int)");
    }

    override protected void initNoArgs() {
        Console.WriteLine("Child initNoArgs");
    }
}
于 2012-07-27T18:28:35.647 回答
0

继承仅作为一种方式起作用。

Child--->Parent

你可能有一个结构错误,因为(如果我错了,有人纠正我)没有场景你必须同时调用同一类的两个构造函数。

除了递归构造函数,因为它调用自己,所以它不是一回事。

于 2012-07-27T18:15:35.980 回答
0

Child(int i)您可以通过像这样定义构造函数来完成问题的第一部分:

public Child(int i) : base(i)
{
    Console.WriteLine("Child ctor(int)");
}

但是,如前所述,您不能随后调用另一个Child' 构造函数。如果您的实际目标(假设这不是一个纯粹的学术问题)是确保Child始终执行包含在 ' 的默认构造函数中的某些标准行为,则最好将其封装在一个方法中并从Child' 的每个构造函数中调用它:

public class Child:Parent
{
    public Child()
    {
        Console.WriteLine("Child ctor()");
        CommonChildConstructionBehaviour();
    }

    public Child(int i) : base(i)
    {
        Console.WriteLine("Child ctor(int)");
        CommonChildConstructionBehaviour();
    }

    private void CommonChildConstructionBehaviour()
    {
        Console.WriteLine("All child constructors must call me.");
    }
}
于 2012-07-27T18:19:43.133 回答
0

有几个选择,但没有一个是完美的。最后,如果可以(显然),我的主要建议是升级到 .NET 4.0。

这是一种选择,使用一个对象,然后将其转换为您需要的任何内容。这是明显的缺点,因为您将丢失打字或破坏签名,但它可能适用于您的情况,我不知道:

public class Parent3
{
    public Parent3(object i)
    {
        Console.WriteLine("Parent3 ctor()");

        if (i != null)
        {
            Console.WriteLine("Parent3 ctor(int)");
        }
    }
}

public class Child3 : Parent3
{
    public Child3(object i)
        : base(i)
    {
        Console.WriteLine("Child3 ctor()");

        if (i != null)
        {
            Console.WriteLine("Child3 ctor(int)");
        }
    }
}

这是另一种选择,使用 Init 方法。但是,它们不会以完全相同的顺序触发,但它可能对您有用。

    public class Parent
{
    public Parent()
    {
        Init();
    }

    protected void Init()
    {
        Console.WriteLine("Parent ctor()");
    }

    public Parent(int i)
    {
        Init(i);
    }

    protected void Init(int i)
    {
        Console.WriteLine("Parent ctor(int)");
    }
}

public class Child : Parent
{
    public Child()
    {
        Init();
    }

    protected void Init()
    {
        Console.WriteLine("Child ctor()");
    }

    public Child(int i)
    {
        Init(i);
        base.Init(i);
        Init();
    }


    protected void Init(int i)
    {
        Console.WriteLine("Child ctor(int)");
    }

}

那么这是一种我真的不推荐的方法,但无论如何我都会包括它

    public class Parent
{
    public Parent()
    {
        Console.WriteLine("Parent ctor()");
    }

    public Parent(int i)
    {
        Console.WriteLine("Parent ctor(int)");
    }
}

public class Child : Parent
{
    private static int _i; //this is likely to blow up at some point.

    public Child() : base(_i)
    {
        Console.WriteLine("Child ctor()");
    }

    public Child(int i) : this()
    {
        _i = i;
        Console.WriteLine("Child ctor(int)");
    }
}
于 2012-07-27T18:40:33.000 回答