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

C#-使用继承和运算符重载设计类,c#,C#,我有两个类,它们代表一种特殊的数值。让我们称一个“值”和一个“分数”;分数由类型值的分子和分母组成。因为这些是数值,所以运算符重载(+-*/)很有意义。鉴于值的性质,除法返回一个分数。可以混合使用值和分数执行操作 目前,我刚刚定义了一个从值到分数的隐式cast操作符(以及从分数到值的显式cast操作符,尽管我没有使用它),并且没有使用任何类型的继承 我想知道是否有任何“优雅”的方式来定义这两个方面的抽象基类,它定义了一组可用的操作,并调用了适当的操作。效率是一个问题。我宁愿在必要时只使用分数,也

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

目前,我刚刚定义了一个从值到分数的隐式cast操作符(以及从分数到值的显式cast操作符,尽管我没有使用它),并且没有使用任何类型的继承

我想知道是否有任何“优雅”的方式来定义这两个方面的抽象基类,它定义了一组可用的操作,并调用了适当的操作。效率是一个问题。我宁愿在必要时只使用分数,也不愿在两种情况下分别定义更复杂的操作,因为它们可以使用相同的语法表示

我可以看到的一种方法是对每个操作执行如下操作,但我想知道是否有更好的方法来执行此操作

    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;
    }

事实上,我认为最“优雅”的方式是分别定义每个变体

优点:

  • 编译器在编译时(应该在编译时进行)而不是在运行时选择适当的计算
  • 每个计算方法只包含计算代码
缺点是:

  • 这是一个多一点的代码(只是学习该死的类型)
那么,让我们看看,你有:

  • 分数
  • 分数op值
  • 值运算分数
  • 值op值

乘以4次操作,总共只授予16个方法,每个方法大约有一行。

如果您的基类必须执行一些操作,例如尝试强制转换到子类型并检查其是否有效,这表明基类不应该实现此方法。理论上,基类不应该知道任何特定的子类


在建议的实现中,如果要添加另一个子类,则需要去编辑基类。继承的全部意义在于,您可以添加新类型,而无需编辑现有对象。

公共静态分数运算符*(值a,分数b)在AbstractValue中无效,因为两个操作数都不是AbstractValue类型。请理解这一点。您对替代实施有何建议?您是否找到了解决此问题的好方法?