[英]Problem with constructors and inheritance in C#
I am having the following problem: 我有以下问题:
public class A {
public A(X, Y, Z) {
...
}
}
public class B : A {
public B(X, Y) : base(X, Y) {
//i want to instantiate Z here and only then pass it to the base class!
}
}
How can I solve this problem? 我怎么解决这个问题? Is there a way? 有办法吗?
The common solution is to call a static method belonging to the type that can calculate the value of the parameter to be passed to the base constructor. 常见的解决方案是调用属于可以计算要传递给基础构造函数的参数值的类型的静态方法。
For example: 例如:
public B(int x, int y)
: base(x, y, CalculateZ(x, y))
{
}
// You can make this parameterless if it does not depend on X and Y
private static int CalculateZ(int x, int y)
{
//Calculate it here.
int exampleZ = x + y;
return exampleZ;
}
Do note that CalculateZ
cannot be an instance method, because the this
reference is not available in constructor initializers. 请注意, CalculateZ
不能是实例方法,因为this
引用在构造函数初始值设定项中不可用。
From the language-specification 10.11.1 Constructor initializers: 从语言规范10.11.1构造函数初始化器:
An instance constructor initializer cannot access the instance being created. 实例构造函数初始值设定项无法访问正在创建的实例。 Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name. 因此,在构造函数初始值设定项的参数表达式中引用它是一个编译时错误,因为参数表达式通过简单名称引用任何实例成员的编译时错误。
EDIT: Changed 'instance' to 'static' in the description. 编辑:在说明中将“实例”更改为“静态”。
You need to calculate Z before the constructor itself gets called. 您需要在构造函数本身被调用之前计算Z. If it's simple you can use an inline expression, else you'll need to define a helper function. 如果它很简单,你可以使用内联表达式,否则你需要定义一个辅助函数。
Using a helperfunction: 使用辅助功能:
public class A {
public A(X x, Y y, Z z) {
...
}
}
public class B : A {
private static Z calculateZ()
{
}
public B(X x, Y y) : base(X, Y, calculateZ()) {
}
}
Without helperfunction: 没有辅助功能:
public B(X, Y) : base(X, Y, X+Y) {
}
public abstract class A {
public A(X, Y) {
...
}
public abstract Z TheVariableZ{get;set;}
}
public class B : A {
public B(X, Y) : base(X, Y) {
//i can only calculate Z here!
}
public override Z TheVariableZ{//implement it here}
}
And if you can't make A abstract, just mark the property as virtual 如果你不能制作抽象,只需将属性标记为虚拟
Possibly this: 可能是这样的:
public abstract class A {
public A(X, Y) {
CalculateZ();
}
abstract void CalculateZ();
}
public class B : A {
public B(X, Y) : base(X, Y) {
}
override void CalculateZ()
{
... Calculate here.
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.