我有一个类A
,它有5个构造函数:
- 来自
IEnumerable<A>
(例如A(new A[] {A1, A2})
) - 使用
params
从A[]
(上一个的快捷方式,例如A(A1, A2)
) - 来自
Vector<Complex>
- 从
IEnumerable<Complex>
(将枚举数转换为向量并调用前一个,例如A(new Complex[] {Complex1, Complex2})
) - 使用
params
(前一个的快捷方式,例如A(Complex1, Complex2)
)从Complex[]
还有一个类B
,它用3个更具体的构造函数扩展了A
:
- 来自
Complex a, Complex b
- 来自
double a, double b, double c, double d
- 来自
double a, double b
下面的代码:
public class A
{
public A(params A[] array) : this((IEnumerable<A>)array) { }
public A(IEnumerable<A> enumerable)
{
//
}
public A(params Complex[] array) : this((IEnumerable<Complex>)array) { } // Breaks shit
public A(IEnumerable<Complex> enumerable) : this(Vector<Complex>.Build.DenseOfEnumerable(enumerable)) { }
public A(Vector<Complex> vector)
{
//
}
}
public class B : A
{
public B(Complex a, Complex b)
{
//
}
public B(double a, double b, double c, double d)
{
//
}
public B(double a, double b)
{
//
}
}
将具有Complex[]
的构造函数添加到A
后,A
的所有三个构造函数都出现以下错误:
Error CS0121 The call is ambiguous between the following methods or properties: 'A.A(params A[])' and 'A.A(params Complex[])'
我认为构造函数不是继承的,父类中的新构造函数怎么会干扰子类中的构造函数呢?如何解决问题?
我使用的模式允许各种等效类型的输入(例如A(Complex1, Complex2)
、A(ComplexArray)
和A(ComplexVector)
)是一种良好的做法,还是应该采取不同的做法?
构造函数按从基类第一到继承类最后的顺序运行。
public B(Complex a, Complex b)
{
//
}
等于
public B(Complex a, Complex b) : base()
{
//
}
编译器正试图为基类型(a)找到一个不接受任何参数的构造函数。由于params关键字,有两个候选者:
public A(params A[] array) : this((IEnumerable<A>)array) { }
和
public A(params Complex[] array) { }
您收到错误是因为编译器无法决定应该使用哪一个。要解决此问题,可以重写B类的构造函数以使用基类构造函数:
public B(Complex a, Complex b) : base(a, b)
{
//
}
我希望我能正确理解你的问题。
不能重写基类的构造函数。如果B
继承自A
,并且两个类都具有具有相同签名的构造函数,则它将不起作用。基类的构造函数总是被执行的,但如果您仍然需要实现两个具有相同构造函数的构造函数,您可以使用base关键字。
在您的情况下,它应该是:
public class B : A
{
public B(Complex a, Complex b) : base(a, b)
{
// Do some code here
}
public B(double a, double b, double c, double d)
{
//
}
public B(double a, double b)
{
//
}
}
两个构造函数仍在执行,但现在您可以在B
类的构造函数中编写逻辑。