2010-01-06 36 views
1

我正在爲我的學期項目開發單位轉換器。我需要一些關於類/接口/抽象類結構的幫助。我想要一些可以被類繼承的接口或抽象類(DegreesConverter,MassConverter,LenghtConverter)。喜歡也許interface IUnitConvert<Type>。我將面向初學者處理角度(度,弧度,格拉迪),力(牛頓,帕斯卡)和數據(字節,千字節,兆字節,千兆字節,千兆字節)的單位。有什麼建議麼?單位轉換器程序

+0

到目前爲止你有什麼? – John 2010-01-06 22:39:09

+0

對不起,只是用戶界面。 – 2010-01-06 22:46:54

回答

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 
+0

我會使用相同的Distance.Convert方法嗎? – 2010-01-07 22:52:35

+0

是的,對於距離(米,英尺等)的任何兩種實現都是相同的,您將它傳遞給它。 – 2010-01-08 02:13:54

0

有很多不同的方法可以解決這個問題。這是使用代表的一種方法。

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

如果你需要比其他雙打其它類型的,你需要重載轉換方法。

+0

這種方法唯一的問題是你添加更多的單位時會在SizeConverter枚舉中出現組合爆炸 - BytesToKB? MBtoKB?一旦我添加千兆字節會發生什麼? – Paolo 2010-01-06 23:01:14

+0

使用b/kb/mb/gb/tb將有20種方法可用於所有可能的轉換,對吧?考慮到每次轉換基本上是1行代碼,我認爲這不合理。 – mdm20 2010-01-06 23:13:03

+0

你是對的我不認爲這將是你在班級項目範圍內不得不擔心的事情。 – slimbo 2010-01-07 05:02:01

0

想想你會如何使用它,並讓它指導你。例如,你想表示什麼樣的單位?你的基地單位將會是什麼?如何處理度量單位之間的轉換?

對我想我們可以看到你需要一些方法來表示一個度量單位,例如,英尺,米,升,furlongs,度,千克,磅,curies,歐姆等。這似乎是一個階級,或一系列的類 - 也許單位作爲基地,腳,米,升,弗朗斯作爲子類。那麼我認爲你需要一些方法將單位與價值聯繫起來。這個單位/值必須提供某種方式來在相同類型的度量單位(長度/距離,體積,溫度,質量/重量)之間進行轉換,並且足夠亮以便在調用代碼嘗試某些可疑事件時拋出合理的異常如將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應該產生一個新的具有複合單位的單位值 - 在這種情況下,a/b應該產生單位爲英尺/秒(英尺/秒)的UnitValue,其中轉換例程As然後轉換爲其他值,在這種情況下爲每小時英里數。

我希望這有助於激發你的想法。

分享和享受。