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

C# 使用switch语句的最佳实践是什么?嵌套的?具体的,c#,nested,switch-statement,C#,Nested,Switch Statement,只是想知道如果两个代码块都能产生相同的结果,哪种方法会更好: string from = ddFrom.SelectedItem.ToString(), to = ddTo.SelectedItem.ToString(); switch(from) { case "celsius": switch(to) { case "celsius": break;

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


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

谢谢。

第二个更好,结果更快,编码更少,因为它提供了相同的结果。

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

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

第二种方法更可取,因为正如大家所说,它使代码看起来和感觉更好

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

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);
    }
}
当然,这可以进一步改进(首先想到的是使用枚举值而不是温度类型的字符串,还需要进行一些错误检查),但总体思路是这样的


这是一种介于老式的C风格巨型开关和成熟的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");

这两个都很糟糕。您正在对标识符进行硬编码,打开字符串,并将对象定向抛向空中。你为什么不放弃它,试试方法重载呢?嗨,科迪,谢谢你的评论。不幸的是,我们还没有讨论OOP。所以,是的,也许当我们学习OOP时,我会明白你在说什么:)不确定你是如何学习C#与OOP分开的。那一定很混乱。你应该先讨论面向对象编程,然后再学习C。除非你知道工具的用途,否则你无法学会使用它。尽管我不同意没有OO的必要性,但你还是要坚持这一点。它仍然使代码更具可读性,特别是对于具有温度值等自然相似性的事物。我非常同意enum更可取。@CodyGray:我的第一反应是使用
ITempConverter
CelsiusTempConverter
KelvinTempConverter
等作为实现者
ITempConverter.ToNormalized
ITempConverter.FromNormalized
将负责转换,如
result=targetConverter.FromNormalized(sourceConverter.ToNormalized(input)),其中“规范化”是您选择的中间表示形式。但经过一点思考,它确实感觉比必要的更重。谢谢乔恩。太糟糕了,我们仍然使用VS2008,所以我们没有元组。但我会把这个放在书签上。:)
        ITemperatureScale fromScale = TemperatureScaleProvider.GetFromString("celcius");
        ITemperatureScale toScale = TemperatureScaleProvider.GetFromString("KELvIN");