C# - 使用继承和运算符重载设计类

3
我有两个类,代表一种特殊的数字类型。让我们称之为“Value”和“Fraction”; Fraction由类型为Value的分子和分母组成。因为这些是数字值,所以运算符重载(+ - * /)非常有意义。由于Value的性质,除法返回一个Fraction。可以使用Values和Fractions的混合进行操作。
目前,我只定义了一个从Value到Fraction的隐式转换运算符(还有一个从Fraction到Value的显式转换运算符,但我没有使用它),并且没有使用任何继承方式。
我想知道是否有任何“优雅”的方法来在抽象基类中定义这两个类,并调用适当的操作。效率是一个问题。我宁愿只在必要时使用Fraction,也不想在需要时为两种情况分别定义更复杂的操作,而是希望使用相同的语法来表达。
我能看到的一种方法是对每个操作执行以下操作,但我想知道是否有更好的方法?
    public static AbstractValue operator *(AbstractValue a, AbstractValue b)
    {
        Value valA = a as Value;
        Value valB = b as Value;
        if(valA == null)
        {
            Fraction fractA = a as Fraction;
            if(valB == null)
            {
                Fraction fractB = b as Fraction;
                return fractA * fractB;
            }
            return fractA * valB;   
        }
        if(valB == null)
        {
                Fraction fractB = b as Fraction;
                return valA * fractB;
        }
        return valA * valB;
    }

你找到了解决这个问题的好方法吗? - Samik R
2个回答

1

实际上,我认为最“优雅”的方法是分别定义每个变量。

优点:

  • 编译器在编译时(应该在编译时)完成选择正确计算的工作,而不是在运行时完成。
  • 每种计算方法只包含计算代码。

缺点:

  • 需要写更多的代码(学会打字吧)

所以,你有:

  • 分数 op 分数
  • 分数 op 值
  • 值 op 分数
  • 值 op 值

一共4种操作,总共只有16种方法,每种方法可能只有一行代码。


在AbstractValue中,public static Fraction operator *(Value a, Fraction b)是无效的,因为操作数都不是AbstractValue类型。 - lgaud

1
如果基类必须执行诸如尝试转换为子类型并检查是否成功之类的操作,则这表明基类不应该实现此方法。理论上,基类不应该了解任何特定的子类。
使用您提出的实现,如果您想添加另一个子类,则需要去编辑基类。继承的整个目的是您可以添加新类型而无需编辑现有对象。

了解重点。你有关于另一种实现的建议吗? - Samik R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接