开发者

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.To开发者_JS百科String(),
            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).


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜