我已经读过,而不是在派生构造函数中初始化继承成员(在我们的示例中为_c1
):
class A
{
public int _c;
}
class B:A
{
public B(int c)
{
_c = c;
}
}
我们应该在基类构造函数中初始化它们,因为这样我们减少了对继承成员的调用(_c
):
class A
{
public A(int c)
{
_c = c;
}
public int _c;
}
class B:A
{
public B(int c)
: base(c)
{
}
}
如果在基础构造函数中初始化_c
字段,则初始化顺序如下:
1)首先,派生类B
的字段初始值设定项称为
2)然后调用基类A
的字段初始值设定项(此时_c
设置为值0
)
3)调用B’s
构造函数,然后调用A’s
自定义构造函数
4)_c
字段设置为参数c
的值(在A’s
自定义构造函数内)
5)A’s
自定义构造函数返回后,B’s
构造函数执行其代码。
如果在_c
构造函数中初始化B's
字段,则初始化顺序如下:
1)首先,派生类B
的字段初始值设定项称为
2)然后调用基类A
的字段初始值设定项(此时_c
设置为值0
)
3)调用B’s
构造函数,然后调用A’s
默认构造函数
4)A’s
自定义构造函数返回后,B’s
构造函数将_c
字段设置为参数c
的值
据我所知,在两种情况下_c
都被调用了两次,那么我们究竟是如何减少对继承成员_c
的调用呢?
感谢名单
答案 0 :(得分:5)
问题从这里开始:
public int _c;
字段不应该是公开的,因此为了正确地 ,您将拥有一个属性,因此您必须调用set访问器。我认为他们要强调的是:
之间的区别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
(在构造函数中进行字段赋值)
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
但是!这都是微优化。通常,内联的get / set访问器将被内联 - 因此在现实中几乎没有差别。我很乐意拥有:
public int C {get;set;}
答案 1 :(得分:1)
通常你会像这样编写C类:
class A
{
public A(int c) : _c(c)
{
}
public int _c;
}
现在_c只设置一次。
虽然在实践中我认为编译器会对此进行优化,但您的最后一个示例将与此一样快。