使用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;
}
谢谢。     

解决方法

第二种选择是可取的,因为,正如大家都说过的那样,它使代码的外观和感觉更好。 但是,您可能需要考虑使用更具体系结构的选项:
public class TemperatureConverter
{
    private static readonly IDictionary<Tuple<string,string>,Func<double,double>> ConverterMap =
        new Dictionary<Tuple<string,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风格的mega-
switch
和成熟的OO方法之间的一个很好的中间立场方法(这里没有真正的OO需求,因为这个特定的转换问题具有非常简单的域模型)。     ,第二个对于快速结果和更少的编码会更好,因为它给出了相同的结果。     ,最好对代码进行重组,以便具有温度标度类和一个抽象工厂,该抽象工厂根据输入字符串返回对应的实例:
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\");
    ,我认为第二个更好,更直接,更易读。如果需要,第二种方法将来会更易于维护,修改和扩展。     ,选项#2看起来更干净,并且会产生相同的结果