我运行这个开源库,巧妙地命名为Unit Class Library。它的目的,像许多其他人一样,是允许更智能地处理单位(四舍五入,转换等)。这里是图书馆的一个例子
Distance distance = new Distance(DistanceType.Inch, 3);
Area area = distance * distance;
显然,*
运算符在 Distance 类中被重载,如下所示:
public static Area operator *(Distance d1, Distance d2)
{
return new Area(d1, d2);
}
在尝试在实际应用程序中使用该库时,我需要使用这些类型做一些复杂的方程,并且目前必须将我的所有单位减少回任意双精度数来进行数学运算:
假设我们正在计算体积流量
(这只是一个例子。由于积分和导数,我的实际应用程序中的方程以距离 ^ 5th 和其他奇怪的单位结束。)
Volume v = new Volume(VolumeType.CubicMeters, 10);
Time t = new Time(TimeType.Hours, 5);
double volumeAsDouble = v.CubicInches;
double timeAsDouble = t.Seconds;
double flowRateAsDouble = volume / time;
VolumetricFlowRate flowRate = new VolumetricFlowRate(VolumetricFlowRateType.InchesCubedPerSecond, flowRateAsDouble);
这是一个令人不快的解决方案,因为它会导致不必要的转换。这引入了不必要的舍入误差。而且我知道我可以制作一个操作员来处理这个问题。
Tangent
如果您查看库的其余部分,您会发现从传入的值到不同单位的转换被延迟到需要它时。这确保了只要它与给定的单位相同,您将始终返回与输入相同的值。像这样:
Distance distance = new Distance(DistanceType.Inch, 0.0000000012345)
double inches = distance.Inches; //inches will equal 0.0000000012345
// other libraries will convert the input value as soon as the distance object is created.
// That would likely cause the number to be rounded. This library does not convert until a different unit is requested.
end Tangent
我希望能够做到这一点:
VolumetricFlowRate flowRate = volume / time;
无需编辑 Volume 类以包含新运算符。
我可以进入适当的位置并为每个新组合添加一个新的运算符,当它添加到库时应该返回 VolumetricFlowRate,但这很乏味并且违反了开放封闭原则。
有没有人提出一个解决方案的建议,该解决方案可以用每种新类型进行干净扩展,但又不违反开放封闭原则?