C# 如何重构此代码并返回泛型对象?

C# 如何重构此代码并返回泛型对象?,c#,generics,C#,Generics,嗨,我想知道如何在我的矩阵类层次结构中找出一些常见的代码。我有一个抽象的矩阵类和具体的矩阵4,矩阵3,矩阵2类。 我已经删减了下面的代码(可能删除了太多,这可能不会真正编译) 我的问题是在具体类上有一个Submatrix()方法,它根据调用它的对象返回不同的类型。矩阵X4返回矩阵X3,矩阵X3返回矩阵X2。否则,我已经编写了通用的算法,并且感觉它可以重构为基类(请原谅该算法的混乱,这是我第一次天真的尝试) 例如,我想我可以在Matrix4课上做这样的事情: public Matrix3子矩阵(i

嗨,我想知道如何在我的矩阵类层次结构中找出一些常见的代码。我有一个抽象的矩阵类和具体的矩阵4,矩阵3,矩阵2类。 我已经删减了下面的代码(可能删除了太多,这可能不会真正编译)

我的问题是在具体类上有一个Submatrix()方法,它根据调用它的对象返回不同的类型。矩阵X4返回矩阵X3,矩阵X3返回矩阵X2。否则,我已经编写了通用的算法,并且感觉它可以重构为基类(请原谅该算法的混乱,这是我第一次天真的尝试)

例如,我想我可以在Matrix4课上做这样的事情:

public Matrix3子矩阵(int-removeow,int-removeCol)
{
返回矩阵。子矩阵(removeRow,removeCol,4);
}
有没有一种方法可以
在基类中创建新的
矩阵
,而不用做奇怪的/缓慢的反射

使用系统;
公共抽象类矩阵:IEquatable
{
受保护的双[,]数据;
抽象受保护的整数大小{get;}
公共矩阵(双[,]数据)
{
if(data.GetLength(0)!=size | | data.GetLength(1)!=size){
抛出新的ArgumentException(
$“提供的2D数组的长度必须为{size}”+
“在两个维度上。”);
}
这个数据=数据;
}
public double this[intx,inty]=>this.data[x,y];
公共静态T子矩阵(int-removeow、int-removeCol、int-size)
{
//TODO将Matrix4和Matrix3子矩阵()重构到此处,但我认为您无法做到这一点:
返回新的T();
}
}
公共类矩阵4:矩阵
{
受保护覆盖整数大小=>4;
公共矩阵4(双[,]数据):数据库(数据)
{
//什么也不做,调用基类。
}
公共矩阵3子矩阵(int-removeow,int-removeCol)
{
如果(removeRow>size-1 | | removeCol>size-1){
抛出新ArgumentException(“无法删除行或列”+
$“超出矩阵的大小({size})”;
}
double[,]结果=新的double[size-1,size-1];
int skippedRows=0;
int skippedcols=0;
对于(int x=0;x3;
公共矩阵3(双[,]数据):数据库(数据)
{
//什么也不做,调用基类。
}
公共矩阵2子矩阵(int-removeow,int-removeCol)
{
如果(removeRow>size-1 | | removeCol>size-1){
抛出新ArgumentException(“无法删除行或列”+
$“超出矩阵的大小({size})”;
}
double[,]结果=新的double[size-1,size-1];
int skippedRows=0;
int skippedcols=0;
对于(int x=0;x2;
公共矩阵2(双[,]数据):数据库(数据)
{
//什么也不做,调用基类。
}
}

您可能简化得太多,这不是因为编译问题,而是因为在您的案例中创建不同的具体类没有意义

使
矩阵
非抽象,然后根据构建过程中的输入设置大小。然后,当子矩阵化时,大小将自动减小

如果您有更充分的理由创建具体的类,并且调整大小只是为了快速生成具体实例的一种方法,那么我将编辑这个问题,以更好地演示为什么您要寻找抽象,为什么您仍然需要输出具体实例。如果你仍然这样做,也许调查一个与你相关的问题

public class Matrix : IEquatable<Matrix> {

    double[,] data;

    int size { get; private set; }

    public Matrix(double[,] data) {
        if (data.GetLength(0) != data.GetLength(1))
            throw new ArgumentException("The provided 2D array is not square.");
        this.data = data;
        this.size = data.GetLength(0);
    }

    public double this[int x, int y] => this.data[x, y];

    public Matrix Submatrix(
        int removeRow, 
        int removeCol
    ) {

       if (removeRow > size - 1 || removeCol > size - 1) 
            throw new ArgumentException(
                "Cannot remove a row or column " +
                $"outside the size of the matrix ({size})"
            );

        double[,] result = new double[size - 1, size - 1];
        int skippedRows = 0;
        int skippedcols = 0;

        for (int x = 0; x < size; x += 1) {
            if (x == removeRow) {
                skippedRows += 1;
                continue;
            }
            for (int y = 0; y < size; y += 1) {
                if (y == removeCol) {
                    skippedcols += 1;
                    continue;
                }
                result[x - skippedRows, y - skippedcols] = data[x, y];
            }
            skippedcols = 0;
        }

        return new Matrix(result);

    }

    // ... other methods, particularly ones implementing IEquatable

}
公共类矩阵:IEquatable{
双[,]数据;
int size{get;private set;}
公共矩阵(双[,]数据){
if(data.GetLength(0)!=data.GetLength(1))
抛出新ArgumentException(“提供的2D数组不是正方形”);
这个数据=数据;
this.size=data.GetLength(0);
}
public double this[intx,inty]=>this.data[x,y];
公共矩阵子矩阵(
内特罗,
int removeCol
) {
如果(removeRow>size-1 | | removeCol>size-1)
抛出新的ArgumentException(
“无法删除行或列”+
$“超出矩阵的大小({size})”
);
double[,]结果=新的double[size-1,size-1];
int skippedRows=0;
int skippedcols=0;
对于(int x=0;x