c# - 关于继承和运算符重载的 OOP 设计问题

标签 c# oop design-patterns

对于数学包,我正在尝试为不同类型的矩阵创建类,例如典型的矩形矩阵、三角矩阵、对角矩阵等。原因自然是为了节省特殊矩阵的高效存储和高效算法实现。但我仍然希望拥有重载运算符的灵 active ,其中 C = A + B 将 A 和 B 作为任何类型的矩阵并返回相应的结果(如果其中一个操作数是矩形,则结果可以降级为典型的矩形矩阵) .

我想到了 2 个可能的想法,这两个想法都很乱:

(1) 一个 IMatrix 接口(interface),它会列出每种矩阵需要实现的所有方法,例如转置、逆等,每种矩阵的高效实现是不同的。这里有两个问题: (a) 运算符重载是静态方法,因此不能在接口(interface)中列出,甚至不能在实现接口(interface)的基类中列出。运算符重载必须在每个类中单独编写,如果不在客户端代码中进行困惑的类型检查和强制转换,我不可能实现 C=A+B 类型的操作(正如我上面提到的),我真的很想避免. (b) 当我定义运算符重载时,我不能将两个操作数都作为接口(interface):即我不能在 DiagonalMatrix 类中执行以下操作:

public override IMatrix operator +(IMAtrix lhsMatrix, IMatrix rhsMatrix)
{ ... }

(2) 可以有一个 Matrix 类,类中存储一个矩阵类型的变量(可以是一个 Enum)。根据类型,我们可以实现数据结构和算法。然后运算符重载将无缝地工作。这里的一个问题是:(a) 该类可能会很大,可能带有用于在启动特定算法之前检查矩阵类型的 switch-case 语法。对于每个二元运算符,我必须有 n^2 个案例,n 是我要实现的矩阵类型的数量。也可能是一场维护噩梦。

看起来,如果没有运算符重载细节,我本可以使用 Factory patternVisitor pattern ,但操作重载并非如此。解决这个问题的最佳方法是什么?

目前我找到的资源:

  1. 一个 related thread在这里。
  2. Explanation of a similar problem面对另一个 OS C# Numerics 包的开发者。

编辑:

2011 年 4 月 25 日:添加了迄今为止我发现的有关此问题的更多资源。

最佳答案

如果这是我的项目,我会采用 #1 的变体:定义一个抽象 Matrix 类,它由更具体的类型(如 TriangularMatrix)继承。这将允许您创建运算符(即使所述运算符只是抛出 NotImplementedException),然后您可以在派生类中覆盖这些运算符。它还将允许您将任何矩阵作为矩阵处理,并具有一组通用的功能。

您唯一会丢失的是编译器检查您是否确实覆盖了方法和运算符;由于运算符是静态的,因此不能将它们抽象化。如果您希望让基类中的运算符简单地调用可以在基类中抽象的等效命名方法(例如,+ 将调用 Add 方法),从而强制子类实现它,则可以解决此问题。

数学问题:可以将三角矩阵加到矩形矩阵上,还是两个加数的类型和/或维数必须匹配?如果是前者,请考虑在 Matrix 基类中实现运算符,并让该运算符实现一个策略模式,调用可以对每种类型组合执行实际操作的内部类。如果是后者,只需覆盖该类型矩阵的有效运算符的基类实现即可。

关于c# - 关于继承和运算符重载的 OOP 设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5019683/

相关文章:

c# - 防止在 C++ 中创建虚方法表

c# - WPF按钮命令模式:Interpret to UML diagram to show actors

python - 哪个异常通知子类应该实现一个方法?

spring-boot - 为什么我不应该在一个 Controller 类中调用多个服务?

c# - 带有 ListView 和 Repeater 的 ASP.NET 中的模型 View 展示器

c# - 访问父表单

oop - 我可以根据参数的数量重载类型绑定(bind)过程吗?

c# - 在 C# 层次结构中重写(隐藏、重载?)具有不同返回类型的方法

java - 将 GWT 与持久对象一起使用的正确方法是什么?

c# - 追踪黑客/恶意软件企图