使用switch语句的最佳做法是什么?拼图?具体?

时间:2011-05-25 09:59:50

标签: c# nested switch-statement

只是想知道如果两个代码块都会产生相同的结果,哪种方法会更好:


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 个答案:

答案 0 :(得分:11)

第二个选项更可取,因为正如大家所说,它使代码看起来更好。

但是,您可能需要考虑更具架构的选项:

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和完整的OO方法之间的良好中间路径(这里没有真正需要OO,因为这个特定的转换问题有一个非常简单的域模型)。

答案 1 :(得分:1)

第二个对于快速结果和更少编码会更好,因为它给出了相同的结果。

答案 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");

答案 3 :(得分:0)

我认为第二个更好,更直接,更具可读性。如果需要,第二种方法将来更容易维护,修改和扩展。

答案 4 :(得分:0)

选项#2看起来更干净,会产生相同的结果