2011-05-25 54 views
2

只是想知道哪種方法會更好,如果代碼塊都將產生相同的結果:使用switch語句的最佳做法是什麼?拼圖?具體?

 

string from = ddFrom.SelectedItem.ToString(), 
      to = ddTo.SelectedItem.ToString(); 

switch(from) 
{ 
    case "celsius": 
     switch(to) 
     { 
      case "celsius": 
       break; 
      case "fahrenheit": 
       break; 
      case "kelvin": 
       break; 
     } 
     break; 

    case "fahrenheit": 
     switch(to) 
     { 
      case "celsius": 
       break; 
      case "fahrenheit": 
       break; 
      case "kelvin": 
       break; 
     } 
     break; 

    case "kelvin": 
     switch(to) 
     { 
      case "celsius": 
       break; 
      case "fahrenheit": 
       break; 
      case "kelvin": 
       break; 
     } 
     break; 
} 
 

或者這一個:

 

string from = ddFrom.SelectedItem.ToString(), 
      to = ddTo.SelectedItem.ToString(), 
      conversion = from + to; 

switch(conversion) 
{ 
    case "celsiusfahrenheit": 
     break; 
    case "celsiuskelvin": 
     break; 
    case "fahrenheitcelsius": 
     break; 
    case "fahrenheitkelvin": 
     break; 
    case "kelvincelsius": 
     break; 
    case "kelvinfahrenheit": 
     break; 
} 
 

感謝。

+5

兩個這些*是可怕的*。你對標識符進行硬編碼,切換字符串,並將物體方向引向風中。你爲什麼不放棄,並嘗試方法重載呢? – 2011-05-25 10:10:25

+0

嗨科迪,感謝您的意見。不幸的是,我們還沒有討論OOP。所以是的,也許當我們通過面向對象的時候,我會明白你在說什麼:) – dork 2011-05-26 00:16:28

+3

不知道你如何從OOP中分離出C#。這一定很混亂。 – 2011-05-26 09:09:04

回答

8

第二個選項是優選的。

但是,您可能要考慮更多的架構選項:

public class TemperatureConverter 
{ 
    private static readonly IDictionary<Tuple<string, string>, Func<double, double>> ConverterMap = 
     new Dictionary<Tuple<string, string>, Func<double, double>> 
     { 
      { Tuple.Create("celsius", "kelvin"), t => t + 273 }, 
      // add similar lines to convert from/to other measurements 
     } 

    public static double Convert(double degrees, string fromType, string toType) 
    { 
     fromType = fromType.ToLowerInvariant(); 
     toType = toType.ToLowerInvariant(); 
     if (fromType == toType) { 
      return degrees; // no conversion necessary 
     } 

     return ConverterMap[Tuple.Create(fromType, toType)](degrees); 
    } 
} 

用法:

TemperatureConverter.Convert(0, "celcius", "kelvin"); 

當然,這可以進一步提高(採用枚舉值的字符串而不是對溫度類型首先想到的是,還有一些錯誤檢查是按順序的),但總的想法就在那裏。這是一個很好的中間地帶的方法之間的老學校C型大型switch和全面的面向對象方法(在這裏沒有真正的需要面向對象,因爲這個具體的轉換問題有一個非常簡單的領域模型)。

+0

注意這一點,即使我不同意不需要面向對象。它仍然使代碼更具可讀性,特別是對於與溫度值具有如此自然相似性的東西。我*強烈同意,枚舉將是可取的。 – 2011-05-25 10:24:20

+0

@CodyGray:我的第一反應是將一個'CempConverter'和'CelsiusTempConverter','KelvinTempConverter'等作爲實現者。 'ITempConverter.ToNormalized'和'ITempConverter.FromNormalized'將負責轉換,如'result = targetConverter.FromNormalized(sourceConverter.ToNormalized(input));',其中「標準化」是您選擇的中間表示形式。但是經過一番思考,它肯定感覺比必要的更重量級。 – Jon 2011-05-25 10:36:08

+0

謝謝喬恩。太糟糕了,我們仍在使用VS 2008,所以我們沒有Tuples。但我會保留這個書籤。 :) – dork 2011-05-26 00:43:12

1

第二個對於快速結果和更少的編碼會更好,因爲它給出了相同的結果。

0

我認爲第二個更好,更直接,更具可讀性。如果需要,第二種方法在將來更容易維護,修改和擴展。

0

選項#2似乎更清潔,因爲,大家都已經表示,它使代碼的外觀和感覺更好的將產生相同的結果

1

這是更好地調整你的代碼,所以你有溫度的規模類和抽象工廠,返回相應的實例基礎輸入字符串:

public interface ITemperatureScale 
{ 
    double GetAbsoluteValue(); 
    ITemperatureScale ConvertTo(ITemperatureScale temperatureScale); 
} 

public class CelciusScale : ITemperatureScale 
{ 
    public double GetAbsoluteValue() 
    { 
     throw new NotImplementedException(); 
    } 

    public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class FarScale : ITemperatureScale 
{ 
    public double GetAbsoluteValue() 
    { 
     throw new NotImplementedException(); 
    } 

    public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class KelvinScale: ITemperatureScale 
{ 
    public double GetAbsoluteValue() 
    { 
     throw new NotImplementedException(); 
    } 

    public ITemperatureScale ConvertTo(ITemperatureScale temperatureScale) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public static class TemperatureScaleProvider 
{ 
    private const string SCALE_CELSIUS = "celsius"; 
    private const string SCALE_KELVIN = "kelvin"; 
    private const string SCALE_FAHRENHEIT = "fahrenheit"; 

    public static ITemperatureScale GetFromString(string temperatureScaleString) 
    { 
     //Some input checks here 
     switch (temperatureScaleString.ToLowerInvariant()) 
     { 
      case (SCALE_CELSIUS): 
       return new CelciusScale(); 
      case (SCALE_KELVIN): 
       return new KelvinScale(); 
      case (SCALE_FAHRENHEIT): 
       return new FarScale(); 
      default: 
       throw new ArgumentException("temperatureScaleString"); 
     } 

    } 
} 

用法是:

 ITemperatureScale fromScale = TemperatureScaleProvider.GetFromString("celcius"); 
     ITemperatureScale toScale = TemperatureScaleProvider.GetFromString("KELvIN"); 
相關問題