我正在使用一个类库,用于各种度量单位。我试图避免尽可能多地重复代码,这应该非常简单,因为从数学上来说,将两个长度加在一起还是将两个速度加在一起并不重要-您只需将它们转换为相同的单位,然后加。我thought使用基类和泛型可以很容易地做到这一点...
// A measurement consists of a Value (double) and
// a Unit (an Enum for the various unit types).
public class Measurement<TUnit>
where TUnit : struct
{
protected Measurement(double value, TUnit unit)
{
_value = value;
_unit = unit;
}
protected double _value;
protected TUnit _unit;
public double Value => _value;
public TUnit Unit => _unit;
...
// Conversion Methods - these will get overridden in the derived classes.
protected virtual double GetValueAs(TUnit unit) => throw new NotImplementedException();
...
// Operator overloads
public static Measurement<TUnit> operator +(Measurement<TUnit> left,
Measurement<TUnit> right)
{
return new Measurement<TUnit>(left.Value + right.GetValueAs(left.Unit), left.Unit);
}
}
并且此类为每个单元派生,如下所示:
public sealed class Length : Measurement<LengthUnit>
{
// Using a private constructor and public static factory methods
private Length(double value, LengthUnit unit)
: base(value, unit) { }
...
}
我的问题是,每当我尝试使用任何返回Measurement<TUnit>
的基类类型时,这些方法显然都会返回Measurement<TUnit>
对象。
Length length1 = Length.FromMeters(1); // length1 is 1 meter
Length length2 = Length.FromMeters(2); // length2 is 2 meters
Length length3 = length1 + length2; // Error CS0266: Cannot implicitly convert type
// 'Measurement<LengthUnit>' to 'Length'.
// An explicit conversion exists (are you missing a cast?)
var varlength3 = length1 + length2; // This works, but varlength3 is type Measurement<LengthUnit>
// so I can't use any methods in the Length class.
我想念的是什么?甚至有可能做我想做的事情?我需要咬一口子,然后将相同的代码复制到每个单元类中吗?
检查操作员过载:
// Operator overloads
public static Measurement<TUnit> operator +(Measurement<TUnit> left,
Measurement<TUnit> right)
{
return new Measurement<TUnit>(left.Value + right.GetValueAs(left.Unit), left.Unit);
}
您正在返回Measurement<TUnit>
对象。因此,无法确定Measurement<TUnit>
类是否始终是长度对象的编译器,需要进行类似于
Length length3 = (LengthUnit)(length1 + length2;
您可以通过创建用于添加Length
的新运算符来添加Length
对象来避免这种情况。