如果泛型类的泛型类型具有这些运算符,如何重载泛型类上的运算符?

How to overload operators on a generic class if its generic type has those operators?

提问人:Thomas 提问时间:10/23/2023 更新时间:10/23/2023 访问量:44

问:

假设我有一个泛型矩阵类型:

class Matrix<T>
{
    private T[,] _data;
}

且仅当运算符重载时,是否可以使运算符重载?+Matrix<T>T+

最近写了很多 Rust,我希望这能起作用:

class Matrix<T>
{
    private T[,] _data;

    public static Matrix<T> operator+(Matrix<T> lhs, Matrix<T> rhs)
        where T: IAdditionOperators<T>
    {
        // ...
    }
}

可悲的是,它只能应用于方法本身的泛型参数,而不能应用于其包含类的泛型参数。where

我知道我可以删除该子句并在方法主体中使用来执行加法,但在我的情况下,性能影响是不可接受的。wheredynamic

这个问题是类似的,但可以通过 C# 11 中的新接口来解决。但是,我希望我的类型也适用于没有加法运算符的类型。(不过,如果在运行时检查也没关系。IAdditionOperator<T>Matrix<T>T

也许是带有子类和隐式转换的东西?

C# 泛型运 算符重载

评论

0赞 Renat 10/23/2023
在这个特定的例子中,想知道为什么不直接做?即在类级别上添加约束。因为对我来说,很难想象如果 T 不是 IAdditionOperators,那么 Matrix<T> 会是实用的,即使有必要,也可能有一个单独的矩阵类class Matrix<T> where T: IAdditionOperators<T, T, T>
1赞 Thomas 10/23/2023
Matrix只是一个例子;例如,我的实际类也与 S 一起使用。enum

答:

1赞 JonasH 10/23/2023 #1

据我所知,这目前是不可能的。

最简单的解决方法是扩展方法:

static class MatrixExt{
    public static Matrix<T> Add(this Matrix<T> a, Matrix<T> b) where T: IAdditionOperators<T>{
          ...
     }
}

这将要求实际数据以某种方式公开访问。

已经有关于“扩展运算符”的讨论,但没有添加到语言中。

评论

0赞 Thomas 10/24/2023
谢谢。是的,我想我将不得不忍受这种更笨拙的语法。