【问题标题】:How do I overload operator for a generic class? [duplicate]如何为泛型类重载运算符? [复制]
【发布时间】:2010-10-21 14:11:45
【问题描述】:

在我看来,这不仅仅是我的问题。
请不要重复关闭我的问题,因为我查看了这些问题但没有找到解决方案。

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!");
        }

你知道编译器告诉什么:“运算符'-'不能应用于'T'和'T'类型的操作数”,这适用于所有运算符。
那么,对此最好的决定是什么?据我所知,接口不能包含运算符,因此唯一的方法是 T 类型的抽象基类。而且,正如我发现的那样,操作符不能定义为抽象的。

【问题讨论】:

  • @ShuggyCoUk - 实际上,dynamic(在 C# 4.0 中)确实支持运算符。所以这工作,但会更慢。
  • 对不起 - 我应该说得更清楚。 Dynamic 仍然不允许您对泛型类型执行此操作,它允许您将 cast 转换为动态 then 对任何支持它的操作执行操作。如果最终用户只是想使用正确的运算符(放弃所有编译检查),那么这很好。如果他们想获得与原语或结构(可能的情况)的性能相近的东西,他们不会。

标签: c# generics operator-overloading


【解决方案1】:

您可以重载运算符,但编译器不知道如何添加两个未知的泛型类型 (T + T),并且您无法添加约束,因为运算符是静态成员。

一种方法(.Net 2.0 中的[Edit])是在 Matrix 的静态构造函数中为所有运算符方法创建一个工厂,这可以为值类型 T(例如,基于其 TypeCode),或者为不受支持的值类型抛出 NotImplementedException。但这样一来,您就没有编译时检查。

[编辑]在 .Net 3.5 中,您实际上可以使用表达式树获取泛型参数的运算符:https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html

您也可以查看此链接:http://msdn.microsoft.com/en-us/library/system.linq.expressions.binaryexpression.aspx

【讨论】:

    【解决方案2】:

    上一个答案(已链接)解释了大部分内容;相关示例(在 .NET 3.5 中使用 MiscUtil) - Complex&lt;T&gt;

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 可能是因为 OP 没有找到它! ;-)
      猜你喜欢
      • 2016-01-25
      • 2012-12-10
      • 2015-05-23
      • 2017-04-28
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      相关资源
      最近更新 更多