用于自定义矩阵 class 的 C# 集合初始化语法?

C# Collection initialization syntax for use with custom matrix class?

我正在创建一个自定义矩阵 class,它只有一个二维数组来保存所有内容(我知道一维数组更快更好,但这不是这个实现的重点)事情是,我想要一个构造函数,并且能够做类似

的事情
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() 方法?

试试这个代码。您的添加方法必须是 public。此外,为了使代码安全,您必须添加验证器来检查 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矩阵的行都填满时会抛出异常。

如果你想使用集合初始化语法,磁控管的答案就是这样做的方法。这对于锯齿状数组而不是二维数组会更好;正如他指出的那样,不可能进行编译时检查以确保初始化程序中的参数数量与矩阵的大小相匹配,因此您将面临运行时错误的风险,只是初始化 class.

另一种方法是实现一个允许您初始化矩阵的替代构造函数,如下所示:

public Matrix(double[,] source)
{
    m = source;
}

那么您的代码行将如下所示:

Matrix a = new Matrix(new double[,]{ {1,2},{3,4} });

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

我知道我迟到了,但是 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 }
        };
    }
}