I'm not sure if this is possible, but if it is then it would be useful.
I am attempting to program in a class called Matrix<T>
. The intent is to be able to have matrices of various data types, such as integers, floats, doubles, etc.
I now want to define addition:
public static Matrix<T> operator +(Matrix<T> first, Matrix<T> second)
{
if (first.dimension != second.dimension)
{
throw new Exception("The matrices' dimensions do not match");
}
Matrix<T> add = new Matrix<T>(first.dimension);
for (int i = 1; i <= first.rows; i++)
{
for (int j = 1; j <= first.columns; i++)
{
add[i,j] = first[i,j] + second[i,j];
}
}
return add;
}
There is an issue with the line add[i,j] = first[i,j] + second[i,j];
since the operation +
is not defined on a general object of type T
.
I only want to specify matrices where T
is a type such that addition is defined, however. So, I can make a matrix of int
s, float
s, double
s, etc. but if I were to try and define a matrix of, say, int[]
s, I would want this to throw an exception since +
is not defined for int[]
s.
So, instead of writing T
, is there some way of telling the computer "this can take in any generic type, as long as an operator +
is defined on the type? Or, is this not possible and I would have to sepeately define a matrix of int
s, matrix of float
s, and so on?
Edit: I don't see how the linked question from closure is related to this - I see nothing about operators there. If they are related, can somebody explain how?
Currently it is not possible (at least without losing compile time safety or changing the API) but with preview features enabled and System.Runtime.Experimental
nuget you can use IAdditionOperators
to restrict T
to have +
operator defined. I would say that adding this interface also to Matrix
itself can be a good idea:
class Matrix<T> : IAdditionOperators<Matrix<T>, Matrix<T>, Matrix<T>> where T : IAdditionOperators<T, T, T>
{
public static Matrix<T> operator +(Matrix<T> left, Matrix<T> right)
{
// swap to real implementation here
T x = default;
T y = default;
Console.WriteLine(x + y);
return default;
}
}
See also: