Я создаю класс Matrix на C# и хотел бы, чтобы он мог включать любой тип, реализующий интерфейс INumber. Я не уверен, как реализовать сложение матриц с разными универсальными типами, например. Matrix<int>
и Matrix<float>
.
public class Matrix<T> where T: INumber<T>
{
private int _width, _height;
private T[,] _vals;
... // implementation of the rest of the class
public static Matrix<T> operator+(Matrix<T> first, Matrix<T> second) {
throw new NotImplementedException();// this stuff is fine
}
}
В настоящее время у меня это есть, но это позволяет вам добавлять только две матрицы одного и того же универсального типа. Я знаю IAdditionOperators<TSelf, TOther, TResult>
, но не знаю, как использовать его в своем коде. Я также не уверен, как следует определять новый тип, т. е. если я добавлю Matrix<int>
и Matrix<float>
, логически он должен вернуть Matrix<float>
, но я не знаю, как это будет решено.
Я скорее подозреваю, что ты не можешь. На float
или int
нет ничего, что говорило бы, что его можно преобразовать в/из другого
Стоит ли обобщать матрицу, где, вероятно, double
подойдет для всех случаев?
Я подозреваю, что лучшее, что вы можете сделать, это скопировать, например. Vector128<T>
и, например. метод расширения Matrix<int>
, называемый ConvertToSingle
, который преобразует его в Matrix<float>
. (Досадно, что вам приходится делать это с помощью методов расширения, поскольку вы не можете определить член/оператор, который применяется только, например, Matrix<int>
). См., например. здесь.
Вы можете создать метод расширения в форме
public static Matrix<T1> Add<T1, T2>(this Matrix<T1> m1, Matrix<T2> m2)
where T1 : INumber<T1>, IAdditionOperators<T1, T2, T1>
where T2 : INumber<T2>
Проблема с этим подходом в том, что я не думаю, что какой-либо примитивный числовой тип реализуется IAdditionOperators
для разных типов.
Возможно, лучший подход — использовать преобразования:
public void Add<T2>(Matrix<T2> other) where T2 : INumber<T2>
{
var result = new Matrix<T>(_width, _height);
for (int i = 0; i < _width; i++)
{
for (int j = 0; j < _height; j++)
{
result._vals[i, j] = _vals[i,j] + T.CreateChecked(other._vals[i,j]);
}
}
}
Просто обратите внимание, что это может привести к сбою во время выполнения, если тип не поддерживает это конкретное преобразование. Я не уверен, можно ли реализовать это с помощью оператора вместо метода, я не был в курсе всех функций C#.
Вы уверены, что хотите сделать это, а не просто сначала преобразовать одну из матриц в тип другой?