Search code examples
c#typesoperators.net-generic-math

Is this possible? Specify any generic type as long as the + operation is defined on it


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 ints, floats, doubles, 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 ints, matrix of floats, 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?


Solution

  • 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: