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

时间:2010-08-05 14:09:06

标签: c#

我有两个代表一种特殊数值的类。我们称之为“价值”和“分数”;分数由Value类型的分子和分母组成。因为这些是数值,所以运算符重载(+ - * /)很有意义。鉴于价值的本质,除法返回一个分数。可以使用值和分数的混合执行操作。

目前,我刚刚定义了一个从值到分数的隐式转换运算符(以及从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;
    }

2 个答案:

答案 0 :(得分:1)

实际上,我会看到最“优雅”的方式分别定义每个变体。

优点:

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

缺点:

  • 这是更多的代码(只是学习friggin'类型)

所以,让我们看看,你有:

  • 分数运算
  • 分数值
  • Value op Fraction
  • Value op Value

时间4次操作,总共只提供16种方法,每种方法可能大约一行。

答案 1 :(得分:1)

如果你的基类必须做一些事情,比如试图转换为子类型并检查它是否有效,这表明基类不应该实现这个方法。理论上,基类不应该知道任何特定的子类。

根据您提议的实现,如果您想添加另一个子类,则需要去编辑基类。整个继承点是您可以添加新类型而无需编辑现有对象。

相关问题