使用相同的泛型参数处理float和double类型

时间:2011-08-24 11:12:42

标签: c# generics operator-overloading

说我有:

public class Matrix<T>
{
    T[][] values;
    ...
}

我想添加一个+运算符来处理int,long,float和double或者实现T的+运算符的任何其他类型。

例如(这不起作用,但传达了我想做的事):

public class Matrix<T>
{
    T[][] values;
    ...
    public static Matrix<T> operator +(Matrix<T> A, Matrix<T> B)
    {
        values = ...;
        for (int row = 0; row < rowCount; ++row)
        {
            for (int col = 0; col < colCount; ++col)
            {
                values[row][col] = A.values[row][col] + B.values[row][col];
            }
        }
    }
}

理想情况下,我希望有一种方法可以将T限制为仅定义+运算符以定义编译时错误但运行异常不会失败的类型。 另外,我想添加隐式转换,然后从Matrix<float>添加到Matrix<double>,但这些转换无法在Matrix<T>类中定义,无论如何都是这样的? 我知道可以使用T4模板为每种类型生成一个矩阵,但是需要事先指定类型,我希望这适用于定义运算符的任何类型。

1 个答案:

答案 0 :(得分:0)

您必须创建一个将处理+操作的表达式:

private static Func<T, T, T> Add = InitAdd();
private static Func<T, T, T> AddInit()
  {
    Type type = typeof(T);
    ParameterExpression left = Expression.Parameter(type, "left");
    ParameterExpression right = Expression.Parameter(type, "right");
    return Expression.Lambda<Func<T, T, T>>(Expression.Add(left, right), left, right).Compile();
  }

在+运算符中,您可以调用静态添加函数:

values[row][col] = Add(A.values[row][col], B.values[row][col]);

查看LinqLib.Operators命名空间下的扩展中的http://linqlib.codeplex.com/。这些扩展完全符合您的要求。