简体   繁体   English

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

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

I'm creating a custom matrix class that only has a single 2D array to hold everything (I know that a 1D array is faster and better, but that's not the point of this implementation) the thing is, I'd like to have a constructor, and be able to do something like我正在创建一个自定义矩阵类,它只有一个 2D 数组来保存所有内容(我知道一维数组更快更好,但这不是这个实现的重点)问题是,我想要一个构造函数,并且能够做类似的事情

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

and have it all work out.并让一切顺利。 I've run into the "'Matrix' does not contain a definition for 'Add' and no extension method 'Add' etc."我遇到了“'Matrix'不包含'Add'的定义并且没有扩展方法'Add'等”。 but after looking around, I've yet to be able to find robust enough info on how to define the Add() method in order to make it work.但环顾四周后,我还没有找到足够可靠的信息,说明如何定义 Add() 方法以使其工作。 Here's the code I have so far这是我到目前为止的代码

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];
        }
    ...
    }

so, how would I go about doing the Add() method anyway?那么,无论如何我将如何执行 Add() 方法?

Try this code.试试这个代码。 Your Add method must be public.您的 Add 方法必须是公共的。 Also, to make the code safe, you must add verifiers to check if the sizes of the m matrix and the provided data match.此外,为了使代码安全,您必须添加验证器来检查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++;
}

If you don't provide all the rows, the remaining rows will have the elements with their defaults values.如果您不提供所有行,则其余行将包含具有默认值的元素。 Also, note that this method can be called in the future, and it would throw an exception when the m matrix has all the rows filled.另请注意,此方法可以在将来调用,并且当 m 矩阵已填充所有行时会引发异常。

Magnetron's answer is the way to do it if you want to use the collection initializer syntax.如果您想使用集合初始值设定项语法,磁控管的答案就是这样做的方法。 This would work better with a jagged array instead of a two-dimensional array;这对于锯齿状数组而不是二维数组会更好; as he points out, it's not possible to do a compile time check to ensure that the number of arguments in the initializer matches the size of the matrix, so you're going to risk runtime errors just initializing the class.正如他指出的那样,不可能进行编译时检查以确保初始化程序中的参数数量与矩阵的大小相匹配,因此仅初始化类就会冒运行时错误的风险。

Another approach would be to implement an alternative constructor that allows you to initialize the matrix, like this:另一种方法是实现一个替代构造函数,允许您初始化矩阵,如下所示:

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

Then your line of code would look like this:那么您的代码行将如下所示:

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

This would avoid the issue since the dimensions of the matrix are determined by the dimensions of the initialization data, which must be a two-dimensional array.这将避免这个问题,因为矩阵的维数由初始化数据的维数决定,初始化数据必须是二维数组。

I know I am late, but what about an extension method of double[,] , or even implementing an implicit cast?我知道我迟到了,但是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 }
        };
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM