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



我正在创建一个自定义矩阵类,它只有一个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((方法呢?

试试这个代码。您的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矩阵已填充所有行时,它将抛出异常。

Magnetron的答案是,如果您想使用集合初始值设定项语法,就可以这样做。这将更好地用于锯齿状阵列,而不是二维阵列;正如他所指出的,不可能在编译时进行检查以确保初始化器中的参数数量与矩阵的大小相匹配,因此仅初始化类就可能出现运行时错误。

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

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

最新更新