我正在帮助我的朋友开发一个单位转换器。他问我是否可以帮忙拆分工作。所以我正在创建一个名为Unit的.dll。单位应该处理转换。我是如何做到头脑风暴的,我提出了一个想法,给每个部分一个枚举(如枚举角[度,弧度,格拉通],枚举面积[平方米,平方英里,...],枚举能量[牛顿,帕斯卡,焦耳,......],......)。然后一个主抽象类Unit与所有Convert方法
注意:
我不要求您对.dll进行编码,我只想要您对如何制作.dll的意见。
答案 0 :(得分:2)
当你拥有这样的多对多关系(每个值都希望能够转换为同类中的其他任何类型的值)时需要注意的是,你最终会写出大量的方法,如果你使用强力方法为每种可能性编写转换函数。
如果你需要它尽可能快地工作并且想要确保你的错误得到控制,那么这是可以的,但你的代码可维护性会受到影响。
我过去在许多单元之间进行转换的事情是建立一个“基础”单元,所有东西都可以转换为和编写函数来转换为/从中转换。这使您可以定义如下界面:
interface IUnitConverter<T, U> {
T ToBaseUnit();
void FromBaseUnit(T BaseValue);
U MyValue {get;}
}
并专门针对某些类型的转换:
class RadiansConverter : IUnitConverter<DegreesConverter, float> {
float radians = 0;
DegreesConverter ToBaseUnit() {...}
void FromBaseUnit(DegreesConverter BaseValue) {...}
float MyValue {get {return radians;}}
}
编辑:用法:
// assume we have a constructor that sets the private value
float degrees = new RadiansConverter(Math.PI).ToBaseUnit().MyValue;
float radians = new RadiansConverter().FromBaseUnit(degrees).MyValue;
这可能有点重量级,你必须注意错误的传播,让你进行两次转换而不是一次转换。当我需要进行需要存储状态的复杂GIS转换时,它已派上用场了,但它可能不是您正在寻找的内容。
答案 1 :(得分:1)
我更喜欢这样的设计:
var measure = Angle.FromDegrees(10);
Console.Write(measure.ToRadians());
从编码可用性的角度来看,我没有看到添加枚举的任何安慰。
这类似于例如如何在框架中实现TimeSpan。
答案 2 :(得分:0)
为什么一个.dll?
在那组 x 单位中,你有(如果我记得我的数学正确) x!可能的转换,这在 x时不是问题 = 3,但对于Area来说有点难度,你可以有平方毫米,厘米,米,英寸,英尺,码,链,弗隆或英里,以及公顷和英亩,这是没有旅行到维基百科查找任何更加模糊的内容。 11!只有不到4,000万次可能的转换。
我很想为每个 n 的可兑换单元组成一个.dll(或者更具体地说是一个类,并且可能将所有类放在同一个.dll中) .dll通过一个标准单位转换所有内容,这样您就可以在每次转换中运行一个或两个2( x - 1)个转换计算,比如将所有输入转换为平方米,然后再转出比编码每个可能的组合。二十次转换听起来像一个比四千万更快的开发任务: - )
我肯定会为单位描述建议枚举而不是免费的字符串文字,因为这样可以让您的朋友更容易使用这些类,并巧妙地公开可用转化的选项。
我想不出让所有类实现相同接口的好方法,因为每次转换将从枚举类型(from和to)中获取两个参数,并且枚举对于每个类都是不同的。泛型可能会提供一个更清洁的解决方案,但我现在看不到 - 在我打字的时候其他人已经回答了,但我还没有看到答案。