从基类继承ToString()时的数据类型混淆

时间:2011-05-27 14:31:12

标签: c# inheritance matrix

我正在用C#编写一个用于处理矩阵的类库,目前正在开发一个名为ComplexMatrix的Matrix子类。 Matrix基类使用Int32数据类型的值(更高级版本使用Double),以及System.Numerics.Complex结构的ComplexMatrix(.NET 4)。

对于基类,我将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 in a new,more advanced version);它是ComplexMatrix中的System.Numerics.Complex类型
  • this.Rows,this.Columns属性:矩阵的行数和列数

我有几个问题:

  • 在ComplexMatrix实例上调用ToString并调用基本ToString()方法时,是否尝试从Complex转换为Int32?
  • 由于ComplexMatrix Elements属性(Complex [,] type)隐藏了基类Elements属性(Int32 [,] type),因此需要new关键字?
  • “this”kwyword是否被视为Matrix类型而不是ComplexMatrix?

2 个答案:

答案 0 :(得分:2)

我认为您的问题如下:
Elements类中的virtual属性未标记为MatrixElements类中的ComplexMatrix属性隐藏了Elements类的Matrix属性。因此,多态性不起作用,ToString中的Matrix方法访问Matrix.Elements而非ComplexMatrix.Elements。但由于Elements是属性而您想要更改属性的类型,因此无论如何都不能使用virtual

要解决此问题,您应该执行以下操作:

  • 创建一个通用基类,希望矩阵值的类型为通用参数
  • 创建一个继承自此基类的SimpleMatrix类,并将int作为通用参数传递。
  • 创建一个继承自此基类的ComplexMatrix类,并将Complex作为通用参数传递。

答案 1 :(得分:0)

你无法真正做你想做的事。

问题是C#中的所有数字类型都没有超类。所以你不能在这样的类层次中用一种数字类型替换另一种数字类型(并且仍然对它们进行数学运算)。

您可以做的是创建一个IMatrixElement接口。然后创建实现该接口的具体类MatrixElementInt,MatrixElementDouble,MatrixElementComplex。然后在构造矩阵时提供正确的元素类型。

interface IMatrixElement
{
    IMatrixElement Add(IMatrixElement a, IMatrixElement b);
    IMatrixElement Multiply(IMatrixElement a, IMatrixElement b);
    string ToString();
}