C# 自定义矩阵类的集合初始化语法是什么?

3
我将创建一个自定义矩阵类,只有一个二维数组来保存所有元素(我知道使用一维数组更快更好,但这不是这个实现的重点)。问题在于,我想要有一个构造函数,并且能够像这样做:
Matrix a = new Matrix(2,2){{1,2},{3,4}};

同时让一切正常运作。我遇到了“'Matrix'不包含定义为'Add'的方法,也没有扩展方法'Add'”等问题,但在查找后,我仍然无法找到足够强大的信息来定义Add()方法,以使其正常工作。以下是我目前所拥有的代码:

public class Matrix : IEnumerable
    {
        /* What we know abuot matricies
         * - matricies are defined by rows, cols
         * - addition is element-wise
         */

        public IEnumerator GetEnumerator()
        {
            yield return m;
        }

        private void Add(double a)
        {
            // what exactly should go here anyway?
        }

        private double[,] m;

        public double this[int rows, int cols]
        {
            get => m[rows, cols];
            set => m[rows, cols] = value;
        }       

        public Matrix(int rows, int cols)
        {
            m = new double[rows, cols];
        }
    ...
    }

那么,我该如何实现 Add() 方法呢?

3个回答

2
尝试使用以下代码。您的Add方法必须是公共的。此外,为了使代码更安全,您必须添加验证器来检查m矩阵和提供的数据大小是否匹配。
private int currentRow = 0;
public void Add(params double[] a)
{
    for (int c = 0; c < a.Length; c++)
    {
        m[currentRow, c] = a[c];
    }
    currentRow++;
}

如果您没有提供所有行,剩余的行将具有它们默认值的元素。此外,请注意,该方法可以在未来调用,并且当m矩阵填满所有行时会抛出异常。

谢谢!它运行得很好。由于我将是唯一使用此库的人,潜在的危险将是可以接受的,我只需要小心。 - Raxmo
@Raxmo 另一个选项是使矩阵大小动态化,每当您添加行时重新调整 m 矩阵的大小。这样,您就可以调用 Matrix a = new Matrix(){{1,2},{3,4}}; - Magnetron
目前的实现(在您的帮助下)适用于我的特定用途。然而,在删除行或列时调整矩阵大小实际上会非常有用(用于矩阵数学)。 - Raxmo

1
Magnetron的回答是使用集合初始化器语法的方法。这将更适用于嵌套数组而不是二维数组;正如他所指出的,无法在编译时检查初始化器中的参数数量是否与矩阵的大小匹配,因此只是初始化类会有运行时错误的风险。
另一种方法是实现一个允许您初始化矩阵的替代构造函数,像这样:
public Matrix(double[,] source)
{
    m = source;
}

那么你的代码行应该是这样的:
Matrix a = new Matrix(new double[,]{ {1,2},{3,4} });

这样做可以避免问题,因为矩阵的维度是由初始化数据的维度确定的,而初始化数据必须是一个二维数组。

虽然这种方法足以解决问题,但它不是我所追求的语法类型。尽管如此,实现起来很容易,对其他应用仍是一个不错的解决方案。 - Raxmo

1

我知道我来晚了,但是有没有 double[,] 的扩展方法,甚至实现一个隐式转换?

class Matrix
{
    // Implicit cast
    public static implicit operator Matrix(double[,] array) => new Matrix(array);

    private double[,] source;
    public Matrix(double[,] source)
    {
        this.source = source;
    }
}
static class Extensions
{
    // Extension
    public static Matrix ToMatrix(this double[,] array)
    {
        return new Matrix(array);
    }
}
static class Program
{
    static void Main()
    {
        // Extension
        Matrix a = new double[,] {
            { 1.0, 2.0, 3.0 },
            { 1.0, 2.0, 3.0 },
            { 1.0, 2.0, 3.0 }
        }.ToMatrix();

        // Implicit cast
        Matrix b = new double[,] {
            { 1.0, 2.0, 3.0 },
            { 1.0, 2.0, 3.0 },
            { 1.0, 2.0, 3.0 }
        };
    }
}

我真的很喜欢这个实现。虽然Megatron的回答更直接地回答了我的问题,但这可能会成为我的未来实现。 - Raxmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接