C# Синтаксис инициализации коллекции для использования с пользовательским классом матрицы?
Я создаю пользовательский класс матрицы, который имеет только один 2D-массив для хранения всего (я знаю, что 1D-массив быстрее и лучше, но не в этом смысл этой реализации), дело в том, что я хотел бы иметь конструктор, и сможет сделать что-то вроде
Matrix a = new Matrix(2,2){{1,2},{3,4}};
и все получится. Я столкнулся с "Матрица" не содержит определения для "Добавить" и нет метода расширения "Добавить" и т. Д." но после осмотра я еще не смог найти достаточно надежной информации о том, как определить метод 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()?
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 заполнит все строки.
Я знаю, что опаздываю, но как насчет метода расширения
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 }
};
}
}
Ответ Магнетрона - это способ сделать это, если вы хотите использовать синтаксис инициализатора коллекции. Это будет лучше работать с зубчатым массивом вместо двумерного массива; как он указывает, невозможно выполнить проверку во время компиляции, чтобы убедиться, что число аргументов в инициализаторе соответствует размеру матрицы, поэтому вы рискуете ошибками во время выполнения просто инициализировать класс.
Другой подход заключается в реализации альтернативного конструктора, который позволяет инициализировать матрицу, например так:
public Matrix(double[,] source)
{
m = source;
}
Тогда ваша строка кода будет выглядеть так:
Matrix a = new Matrix(new double[,]{ {1,2},{3,4} });
Это позволило бы избежать этой проблемы, поскольку размеры матрицы определяются размерами данных инициализации, которые должны представлять собой двумерный массив.