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

时间:2018-07-11 18:10:21

标签: c# collection-initializer

我正在创建一个仅具有一个2D数组来容纳所有内容的自定义矩阵类(我知道一个1D数组更快,更好,但这不是此实现的目的),我想有一个构造函数,并能够做类似的事情

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 个答案:

答案 0 :(得分:1)

如果要使用集合初始化语法,则磁控管的答案就是做到这一点。使用锯齿状数组而不是二维数组会更好。正如他指出的那样,不可能进行编译时检查以确保初始化程序中的参数数量与矩阵的大小匹配,因此您将冒着在初始化类时冒运行时错误的风险。

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

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

然后您的代码行将如下所示:

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

这将避免此问题,因为矩阵的维数由初始化数据的维数确定,初始化数据必须是二维数组。

答案 1 :(得分:0)

尝试此代码。您的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矩阵中的所有行均已填充时,它将引发异常。

答案 2 :(得分:0)

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