开发者

How does initializing inherited members inside base class constructor reduce the calls to…?

I’ve read that instead of initializing inherited members ( _c1 in our example ) inside derived constructor:

class A
{
    public int _c;
}

class B:A
{
    public B(int c)
    {
        _c = c;
    }
}

we should initialize them inside base class constructor, since that way we reduce the calls to inherited members ( _c ):

class A
{
    public A(int c)
    {
        _c = c;
    }
    public int _c;
}

class B:A
{
    public B(int c)
        : base(c)
    {


    }
}

If _c field is initialized inside base constructor, the order of initialization is the following:

1) First the field initializers of derived class B are called

2) Then field initializers of base class A are called (at this point 开发者_Go百科_c is set to value 0)

3) B’s constructor is called, which in turn calls A’s custom constructor

4) _c field gets set to value of a parameter c ( inside A’s custom constructor )

5) Once A’s custom constructor returns, B’s constructor executes its code.

If _c field is initialized inside B's constructor, the order of initialization is the following:

1) First the field initializers of a derived class B are called

2) Then field initializers of a base class A are called(at this point _c is set to value 0)

3) B’s constructor is called, which in turn calls A’s default constructor

4) Once A’s custom constructor returns, B’s constructor sets _c field to a value of parameter c

As far as I can tell, in both cases was _c called two times, so how exactly did we reduce calls to inherited member _c?

thanx


The problem starts here:

public int _c;

Fields shouldn't be public, so to do this properly you would have a property, and you would therefore have to call the set accessor. I think what they are trying to highlight is the difference between:

private int c;
public int C {get {return c;} set {this.c=value;} } // ld, ld, st
public Foo(int c) {this.c = c;} // ld, ld, st
...
Foo foo = new Foo(blah); // ld, newobj, st

(which does a field assignment inside the constructor)

vs

private int c;
public int C {get {return c;} set {this.c=value} } // ld, ld, st 
public Foo() {}
...
Foo foo = new Foo(); // newobj, st
foo.C = blah; // ld, ld, callvirt

However! This is all micro-optimisation. Often, trivial get/set accessors will be inlined - so there is very little difference in reality. I would happily just have:

public int C {get;set;}


Normally you would write class C like this:

class A
{
    public A(int c) : _c(c)
    {
    }
    public int _c;
}

And now _c is only set once.

Although in practice I think that compilers optimize this, and your last example will be as fast as this one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜