我正在为我的学期项目开发一个单位转换器。我需要一些关于类/接口/抽象类的结构的帮助。我想要一些可以由类继承的接口或抽象类(DegreesConverter,MassConverter,LenghtConverter)。就像interface IUnitConvert<Type>
一样。我将为初学者处理角度(度,弧度,渐变),力(牛顿,帕斯卡)和数据(字节,千字节,兆字节,千兆字节,太字节)的单位。有什么建议吗?
答案 0 :(得分:2)
首先想到的是System.TimeSpan,其中同一个类代表时间,您可以通过属性以不同的单位访问它。
您可以在内部以某个常量单位(可能是SI)存储该值,并将其转换为属性getter / setter:
Distance d = new Distance;
d.Meters = 5000;
var km = d.Kilometers; // km = 5;
或者您可以为每个单元创建类:
public sealed class DistanceUnit
{
public DistanceUnit(string name, string symbol, double scale)
{
Name = name;
Symbol = symbol;
Scale = scale;
}
public string Name { get; private set; }
public string Symbol { get; private set; }
public double Scale { get; private set; }
}
public abstract class Distance
{
protected Distance(double value)
{
this.Value = value;
}
protected Distance()
{
}
public double Value { get; set; }
public abstract DistanceUnit Unit { get; }
public override string ToString()
{
return this.Value + " " + Unit.Symbol;
}
public static void Convert<TIn, TOut>(TIn original, out TOut result)
where TIn : Distance, new()
where TOut : Distance, new()
{
result = new TOut();
var scale = result.Unit.Scale / original.Unit.Scale;
result.Value = original.Value * scale;
}
}
public sealed class Meter : Distance
{
private static readonly DistanceUnit s_Unit = new DistanceUnit("Meter", "m", 1);
public Meter(double value) : base(value)
{
}
public Meter()
{
}
public override DistanceUnit Unit
{
get { return s_Unit; }
}
}
public sealed class Kilometer : Distance
{
private static readonly DistanceUnit s_Unit = new DistanceUnit("Kilometer", "km", .001);
public Kilometer()
{
}
public Kilometer(double value)
: base(value)
{
}
public override DistanceUnit Unit
{
get { return s_Unit; }
}
}
用于
Meter distanceHome = new Meter(10000);
Kilometer distanceInKMs;
Distance.Convert(distanceHome, out distanceInKMs); // distanceInKMs.Value = 10
答案 1 :(得分:1)
有很多不同的方法可以解决这个问题。这是使用代表的一种方式。
public class Converter
{
public static double Convert(double original, Func<double, double> conversion)
{
return conversion(original);
}
}
public class SizeConverter
{
public static double MegabytesToBytes(double megabytes)
{
return megabytes * 1048576;
}
public static double KilobytesToBytes(double kilobytes)
{
return kilobytes * 1024;
}
}
您可以这样使用:
double result1 = Converter.Convert(2, SizeConverter.MegabytesToBytes);
double result2 = Converter.Convert(2, SizeConverter.KilobytesToBytes);
如果您需要除双精度之外的其他类型,则需要重载Convert方法。
答案 2 :(得分:0)
想想你将如何使用它,并让它指导你。例如,您想要表示哪种度量单位?你的基本单位是什么?如何处理计量单位之间的转换?
我认为我们可以看到你需要某种方式来表示一个测量单位,例如英尺,米,升,弗隆,度,千克,磅,居里,欧姆等。这似乎是一个类或一系列类 - 可能以单位为基础,以英尺,米,升,弗隆为子类。然后我认为你需要一些方法来将一个单元与一个值相关联。这个单位/值必须提供一些方法来转换相同类型的度量单位(长度/距离,体积,温度,质量/重量),并且如果调用代码尝试一些可疑的东西,则要足够明亮以引发合理的异常(例如将27摄氏度转换为英里/小时)。创建单元/值实例的一些方便的方法将是方便的。单位/价值的东西不应该与特定类型或类别的单位联系在一起,但应该能够很好地处理你关心的任何单位。
Codewise我认为这样的事情会很棒:
UnitValue a, b, c;
a = new UnitValue(3 * 5280, Feet);
b = new UnitValue(180, Seconds);
c = (a / b).As(Miles / Hours);
cout << c;
应该有希望打印像
这样的东西60 miles/hour
所以你可以看到将一个UnitValue除以另一个UnitValue应该产生一个带有复合单位的新UnitValue - 在这种情况下,a / b
应该产生一个单位为英尺/秒(英尺/秒)的UnitValue,转换例程As
然后将其转换为其他内容,在这种情况下为每小时英里数。
我希望这有助于激发你的一些想法。
分享并享受。