从基类继承ToString()时数据类型混淆
本文关键字:数据类型 基类 继承 ToString | 更新日期: 2023-09-27 17:58:01
我正在用C#编写一个用于处理矩阵的类库,目前正在处理一个名为ComplexMatrix的矩阵子类。Matrix基类使用Int32数据类型的值(更高级的版本使用Double)和System.Numerics.Complex结构(.NET 4)的ComplexMatrix。
对于基类,我将ToString()重写为:
| 1 2 |
| 3 4 | printed as {{1,2}{3,4}}
System.Numerics.Complex结构重写ToString(),格式为:
a+bi printed as (a,b) where a is real and b is imaginary
在ComplexMatrix中重写ToString时,我只使用了以下方法:
public override string ToString()
{
return base.ToString();
}
不幸的是,对于一个复杂的矩阵,出现了以下情况:
| 1+1i 1+2i |
| 2+1i 2+2i | printed as {{0,0}{0,0}} rather than {{(1,1),(1,2)}{(2,1)(2,2)}}
我为Matrix类编写的原始ToString()代码是:
public override string ToString()
{
StringBuilder matrixString = new StringBuilder();
string comma = "";
matrixString.Append("{");
for (int i = 0; i < this.Rows; i++)
{
matrixString.Append("{");
for (int j = 0; j < this.Columns; j++)
{
if (j == 0) comma = "";
else comma = ",";
matrixString.Append(comma + this.Elements[i, j].ToString());
}
matrixString.Append("}");
}
matrixString.Append("}");
return matrixString.ToString();
}
在上面的代码中:
- this.Elements属性:在Matrix类中,这是Int32类型的二维数组(在更新、更高级的版本中为Double);它是ComplexMatrix中的System.Numerics.Complex类型
- 这个。行,这个。列属性:矩阵的行数和列数
我有几个问题是:
- 当在ComplexMatrix实例上调用ToString并调用基ToString()方法时,是否正在尝试从Complex到Int32的类型转换
- 由于ComplexMatrix Elements属性(Complex[,]type)正在隐藏基类Elements特性(Int32[,]type),是否需要新关键字
- "this"kwyword是否被视为矩阵类型而非ComplexMatrix
我认为您的问题如下:Elements
属性在Matrix
类中未标记为virtual
。ComplexMatrix
类中的Elements
属性隐藏了Matrix
类的Elements
属性。因此多态性不起作用,Matrix
中的ToString
方法访问Matrix.Elements
而不是ComplexMatrix.Elements
。但是,由于Elements
是一个属性,并且您想要更改属性的类型,因此无论如何都不能使用virtual
。
要解决这个问题,你应该这样做:
- 创建一个希望矩阵值的类型作为泛型参数的泛型基类
- 创建一个继承自该基类的
SimpleMatrix
类,并将int
作为泛型参数传递 - 创建一个继承自该基类的
ComplexMatrix
类,并将Complex
作为泛型参数传递
你不能真正做你想做的事。
问题是,对于C#中的所有数字类型,都没有超类。因此,在这样的类继承中,你不能真的用一种数字类型来代替另一种(并且仍然对它们进行数学运算)。
您可以创建一个IMatrixElement接口。然后创建实现该接口的具体类MatrixElementInt、MatrixElementDouble和MatrixElementComplex。然后在构造矩阵时提供正确的元素类型。
interface IMatrixElement
{
IMatrixElement Add(IMatrixElement a, IMatrixElement b);
IMatrixElement Multiply(IMatrixElement a, IMatrixElement b);
string ToString();
}