2

It seems to me that it is not only my problem.
Please do not close my question as a duplicate because I looked these questions through and I did not find the solution.

class Matrix<T> {
        private Int32 rows;
        private Int32 cols;
        private T[,] matrix;

        public Matrix() {
            rows = cols = 0;
            matrix = null;
        }

        public Matrix(Int32 m, Int32 n) {
            rows = m;
            cols = n;
            matrix = new T[m, n];
        }

        public T this[Int32 i, Int32 j] {
            get {
                if (i < rows && j < cols)
                    return matrix[i, j];
                else
                    throw new ArgumentOutOfRangeException();
            }
            protected set {
                if (i < rows && j < cols)
                    matrix[i, j] = value;
                else
                    throw new ArgumentOutOfRangeException();
            }
        }

        public Int32 Rows {
            get { return rows; }
        }

        public Int32 Cols {
            get { return cols; }
        }

        public static Matrix<T> operator+(Matrix<T> a, Matrix<T> b) { 
            if(a.cols == b.cols && a.rows == b.rows) {
                Matrix<T> result = new Matrix<T>(a.rows, a.cols);
                for (Int32 i = 0; i < result.rows; ++i)
                    for (Int32 j = 0; j < result.cols; ++j)
                        result[i, j] = a[i, j] + b[i, j];
                return result;
            }
            else
                throw new ArgumentException("Matrixes don`t match operator+ requirements!");
        }

        public static Matrix<T> operator-(Matrix<T> a, Matrix<T> b) {
            if (a.cols == b.cols && a.rows == b.rows) {
                Matrix<T> result = new Matrix<T>(a.rows, a.cols);
                for (Int32 i = 0; i < result.rows; ++i)
                    for (Int32 j = 0; j < result.cols; ++j)
                        result[i, j] = a[i, j] - b[i, j];
                return result;
            }
            else
                throw new ArgumentException("Matrixes don`t match operator- requirements!");
        }

You know what the compiler tells: "Operator '-' cannot be applied to operands of type 'T' and 'T'", that is for all operators.
So, what`s the best decision for this? As far as I know, interfaces can not contain operators, so the only way is abstract base class for the type T. but also, as I discovered, operatoes can not be defined as abstract.

chester89
  • 8,328
  • 17
  • 68
  • 113
  • 2
    @ShuggyCoUk - actually, `dynamic` (in C# 4.0) *does* support operators. So this *would* work, but would be slower. – Marc Gravell Apr 24 '09 at 11:51
  • 2
    sorry - I should have made it more clear. Dynamic still doesn't let you do it on generic types, it lets you *cast* to dynamic _then_ do the operation on anything that supports it. If the end users simply wants to use the correct operator (dropping all compile checking) then this is fine. If they want to get something remotely close to the performance on primitives or structs (the likely case) they won't. – ShuggyCoUk Apr 24 '09 at 13:41

3 Answers3

3

The previous answer (already linked) explains most of it; for a related example (in .NET 3.5 with MiscUtil) - Complex<T>

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

Why doesn't e.g. Solution for overloaded operator constraint in net generics help you?

Community
  • 1
  • 1
Pontus Gagge
  • 17,166
  • 1
  • 38
  • 51
0

You can overload an operator, but compiler cannot know how to add two unknown generic types (T + T), and you cannot add a constraint because operators are static members.

A way to do it ([Edit] in .Net 2.0) would be to have a factory for all operator methods in a static constructor of your Matrix, which would either create a correct implementation for value type T (based on its TypeCode, for example), or throw a NotImplementedException for non-supported value types. But this way, you don't have compile-time checks.

[Edit] In .Net 3.5 you can actually get operators for generic parameters using Expression trees: https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html.

You can check this link also: http://msdn.microsoft.com/en-us/library/system.linq.expressions.binaryexpression.aspx

tukaef
  • 9,074
  • 4
  • 29
  • 45
vgru
  • 49,838
  • 16
  • 120
  • 201