1

我正在为我的学期项目开发一个单位转换器。我需要一些关于类/接口/抽象类结构的帮助。我想要一些可以被类(DegreesConverter、MassConverter、LenghtConverter)继承的接口或抽象类。像也许interface IUnitConvert<Type>。对于初学者,我将处理角度单位(度、弧度、梯度)、力(牛顿、帕斯卡)和数据(字节、千字节、兆字节、千兆字节、太字节)。有什么建议么?

4

3 回答 3

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
于 2010-01-07T05:28:13.883 回答
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 方法。

于 2010-01-06T22:58:16.627 回答
0

想想你想如何使用它,然后让它指导你。例如,您要表示哪种计量单位?你的基本单位是什么?计量单位之间的转换应该如何处理?

马上,我认为我们可以看到您将需要某种方式来表示测量单位,例如英尺、米、升、弗隆、度、千克、磅、居里、欧姆等。这似乎是一个类,或一系列类 - 可能以 Unit 为基础,以 Feet、Meters、Liters、Furlongs 作为子类。然后我认为你需要一些方法来将一个单元与一个值相关联。这个单位/值必须提供某种方法来在相同类型的测量单位(长度/距离、体积、温度、质量/重量)之间进行转换,并且如果调用代码尝试一些可疑的事情,则必须足够亮以引发合理的异常(例如将 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然后转换例程将其转换为否则,在这种情况下每小时英里数。

我希望这有助于激发您的一些想法。

分享和享受。

于 2010-01-07T03:22:53.043 回答