wpf 单位转换器程序

hzbexzde  于 2023-04-22  发布在  其他
关注(0)|答案(4)|浏览(143)

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

ru9i0ody

ru9i0ody1#

首先想到的是使用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
a6b3iqyw

a6b3iqyw2#

有很多不同的方法可以实现这一点。这里是使用委托的一种方法。

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);

如果需要double以外的其他类型,则需要重载Convert方法。

3npbholx

3npbholx3#

想想你想如何使用它,并让它指导你。例如,你想表示什么样的度量单位?你的基本单位是什么?应该如何处理度量单位之间的转换?
马上,我想我们可以看到,你将需要某种方式来表示一个测量单位,例如英尺,米,升,弗隆,度,千克,磅,居里,欧姆等,这似乎是一个类,或一系列类-也许单位作为基础,与英尺,米,升,然后我想你需要一些方法来将单位和值联系起来。这个单位/值必须提供一些方法来在相同类型的度量单位之间进行转换(长度/距离、体积、温度、质量/重量),并且如果调用代码尝试可疑的东西,则足够明亮以抛出合理的异常(例如将27摄氏度转换为英里/小时)。一些方便的方法来创建单位/值示例会很方便。单位/值的东西应该不要被束缚在一个特定的种类或类别的单位,但应该高兴地能够处理任何单位,你关心扔在它。
在代码方面,我认为这样的东西会很棒:

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应该产生一个单位为Feet per Seconds(英尺/秒)的UnitValue,然后转换例程As将其转换为其他值,在本例中为miles per hour。
我希望这有助于激发你的一些思考。
分享和享受。

vbopmzt1

vbopmzt14#

我只是通过使用矩阵来完成类似的事情

public static class Units
{
    public enum MassUnits
    {
        grams,
        kg,
        lb,
        mg,
        oz
    }
    static readonly double[,] MassConversions = new double[5, 5]
    {   //grams     kg              lb          mg          oz
            {1d,        1/1000d,        1/453.592d, 1000d,      1/28.3495d},    //grams
            {1000d,     1d,             2.20462d,   1000000d,   35.274d},       //kg
            {453.592d,  1/2.20462d,     1d,         453592d,    16d},           //lb
            {1/1000d,   1/1000000d,     1/453592d,  1d,         1/28349.5d},    //mg
            {28.3495d,  1/35.274d,      1/16d,      28349.5d,   1}             //oz
    };

    public static double ConvertQuantity(this double oldQty, MassUnits oldUnit, MassUnits newUnit, int decimals = 2)
    {
        return ConvertQuantity(oldQty, MassConversions[(int)oldUnit, (int)newUnit], decimals);
    }

    public static double ConvertQuantity(this double oldQty, double conversion, int decimals = 2)
    {
        return Math.Round(oldQty * conversion, decimals);
    }

    public static void test()
    {
        var kilos = 5.2;
        var pounds = kilos.ConvertQuantity(MassUnits.kg, MassUnits.lb);
    }
}

相关问题