简体   繁体   English

使用 switch 语句的最佳实践是什么? 嵌套? 具体的?

[英]What would be the best practice for using switch statements? nested? specific?

just wondering which approach would be better if both blocks of code would yield the same result:只是想知道如果两个代码块都会产生相同的结果,哪种方法会更好:


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

or this one:或者这个:


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

Thanks.谢谢。

Second option is preferable because, as everyone has said, it makes the code look and feel better.第二种选择更可取,因为正如大家所说,它使代码的外观和感觉更好。

However, you might want to consider a more architected option:但是,您可能需要考虑一个更具架构性的选项:

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

Usage:用法:

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

Of course this can be further improved (using enumeration values instead of strings for the temperature types comes to mind first, also some error checking is in order), but the general idea is there.当然,这可以进一步改进(首先想到的是使用枚举值而不是温度类型的字符串,还需要进行一些错误检查),但总体思路就在那里。

IMHO this is a good middle ground approach between the old school C-style mega- switch and a full-fledged OO approach (no real need for OO here because this specific conversion problem has a very simple domain model).恕我直言,这是老式 C 风格的大型switch和成熟的 OO 方法之间的一个很好的中间方法(这里实际上不需要 OO,因为这个特定的转换问题有一个非常简单的域模型)。

The, second one would be better for fast result and less coding as it is giving the Same result.第二个对于快速结果和更少的编码会更好,因为它给出了相同的结果。

It is better to restructure your code, so you have temperature scale classes and an abstract factory that returns a corresponding instance basing an input string:最好重构你的代码,这样你就有了温标类和一个抽象工厂,它根据输入字符串返回相应的实例:

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

    }
}

Usage will be:用法将是:

        ITemperatureScale fromScale = TemperatureScaleProvider.GetFromString("celcius");
        ITemperatureScale toScale = TemperatureScaleProvider.GetFromString("KELvIN");

I think second one is better, straight forward and more readable.我认为第二个更好,更直接且更具可读性。 Second approach would be more easy to maintain, modify and expand in future if needed.如果需要,第二种方法将来会更容易维护、修改和扩展。

option #2 seems cleaner and would yield the same result选项 #2 看起来更干净,并且会产生相同的结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM