在调用基础构造函数之前计算值

时间:2017-03-09 12:03:00

标签: c# .net oop

有什么方法可以在后代类构造函数的末尾调用超级构造函数?

它适用于Java,但在C#中,关键字base似乎不等同于Java的超级。

示例:

class CommonChest : BasicKeyChest
{
    public CommonChest()
    {
        Random rnd = new Random();
        int key = rnd.Next(1, 6);
        int coins = rnd.Next(70, 121);
        super(key, coins, "Common");
    }
}

4 个答案:

答案 0 :(得分:5)

不,使用base关键字或Constructor Initializer的概念是首先调用基础构造函数,然后调用子构造函数。因此,首先初始化子节点上的所有公共或共享参数,然后初始化子类的特定属性。这也是abstract类可以拥有构造函数

的原因之一

答案 1 :(得分:3)

没有办法推迟对基础构造函数的调用,它必须在派生构造函数启动之前完成。

但是,您可以在调用基础构造函数之前通过提供传递给基类的表达式在派生构造函数之外执行计算:

class CommonChest : BasicKeyChest {
    public CommonChest()
    :   this(GenTuple()) {
    }
    private CommonChest(Tuple<int,int> keysCoins)
    :   base(keysCoins.Item1, keysCoins.Item2, "Common") {
    }
    private static Tuple<int,int> GenTuple() {
        Random rnd = new Random();
        int keys = rnd.Next(1, 6);
        int coins = rnd.Next(70, 121);
        return Tuple.Create(keys, coins);
    }
}

上面有点棘手:使用一对int的私有构造函数用于将这些int转发给基础构造函数。元组是在GenTuple方法中生成的,在调用base构造函数之前调用

答案 2 :(得分:2)

您可以在对基础构造函数的调用中调用 static 方法:

class CommonChest : BasicKeyChest
{
    public CommonChest() : base(DoSomething())
    {

    }

    private static Tuple<int,int> DoSomething()
    {
        Random rnd = new Random();
        int key = rnd.Next(1, 6);
        int coins = rnd.Next(70, 121);
        return Tuple.Create(key, coins);
    }
}

答案 3 :(得分:0)

这种设计避免了在派生构造函数中从基类访问成员,尽管它尚未初始化,因为它没有调用它的基类构造函数。

想象一下这是可能的:

class MyClass
{
    MyClass()
    {
        var a = base.MyBaseProperty;
        base();
    }
}

a来电之前base()会怎样?当myBaseProperty在基类中声明时,如果基类构造函数不是第一个语句,它将被整体化。

此外,如果您忘记了对base(...)的调用,编译器会通知您,这样您就不会在不调用基类的情况下意外运行构造函数。