Search code examples
c#generics

Adding 2 different generic types that implement INumber


I am making a Matrix class in C#, and would like for it to be able to include any type that implements the INumber interface. I am unsure of how to be able to implement addition for matrices with different generic types e.g. Matrix<int> and 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 
    }
}

Currently I have this, but this only allows for you to add 2 matrices of the same generic type. I am aware of IAdditionOperators<TSelf, TOther, TResult>, but I do not know how to use it in my code. I am also unsure of how the new type should be decided, i.e. if I add Matrix<int> and Matrix<float>, it should logically return a Matrix<float>, but I do not know how this would be decided.


Solution

  • You could create a extension method on the form

    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>
    

    The problem with this approach is that I don't think any of the primitive numerical type implement IAdditionOperators for different types.

    The perhaps better approach is to use conversions:

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

    Just note that this might fail at runtime if the type does not support that specific conversion. I'm not sure if it is possible to implement this with an operator instead of a method, I have not been keeping up to date with all C# features.