【问题标题】:Is there any alternative way of writing this switch statement(C#3.0)是否有任何替代方法来编写此 switch 语句(C#3.0)
【发布时间】:2010-05-08 08:02:38
【问题描述】:

能不能做得更好

public static EnumFactorType GetFactorEnum(string str)
        {
            Standardization e = new Standardization();
            switch (str.ToLower())
            {
                case "beta":
                    e.FactorType = EnumFactorType.BETA;
                    break;
                case "bkp":
                    e.FactorType = EnumFactorType.BOOK_TO_PRICE;
                    break;
                case "yld":
                    e.FactorType = EnumFactorType.DIVIDEND_YIELD;
                    break;
                case "growth":
                    e.FactorType = EnumFactorType.GROWTH;
                    break;
                case "mean":
                    e.FactorType = EnumFactorType.MARKET_CAP;
                    break;
                case "momentum":
                    e.FactorType = EnumFactorType.MOMENTUM;
                    break;
                case "size":
                    e.FactorType = EnumFactorType.SIZE;
                    break;
                case "stat_fact1":
                    e.FactorType = EnumFactorType.STAT_FACT_1;
                    break;
                case "stat_fact2":
                    e.FactorType = EnumFactorType.STAT_FACT_2;
                    break;
                case "value":
                    e.FactorType = EnumFactorType.VALUE;
                    break;
            }
            return e.FactorType;
        }

如果我创建一个静态类(比如常量)并声明像

这样的变量
public static string BETA= "beta";

然后如果我尝试将它放在 Case 表达式中,例如

Case Constants.BETA : e.FactorType = EnumFactorType.BETA;
                        break;

那么编译器会报错。(很期待)

那么还有其他方法吗?(我无法更改switch语句)

使用 C#3.0

谢谢

【问题讨论】:

  • 如果您可以更改switch 语句,请使用Enum.Parse
  • @KennyTM:但是,开关中的某些字符串与枚举中的名称不对应。

标签: c#-3.0


【解决方案1】:

您可以将Dictionary<string, EnumFactorType> 定义为“映射”并改用它。它本质上是相同的逻辑,但可以更具可读性。

一、映射对象:

private Dictionary<string, EnumFactorType> _mapping = new Dictionary<string, EnumFactorType>
{
    { "beta", EnumFactorType.BETA },
    { "bkp", EnumFactorType.BOOK_TO_PRICE },
    // etc
}

然后在你的方法中:

e.FactorType = _mapping[str.ToLower()];

您可能需要先调用 _mapping.ContainsKey(str) 以确保映射存在。

【讨论】:

  • 如果您需要确保映射存在,请改用TryGetValue 方法。否则,您将进行两次相同的查找。
  • 可能想让 _mapping 静态化;您不想为每个实例生成一个,对吗?
【解决方案2】:

用途:

public const string BETA = "beta";

工作正常。你声明它的方式,它是一个变量。 case 表达式中不允许使用变量。通过使用 const 关键字,你告诉编译器它实际上是一个常量,正如你的类名所暗示的那样。

“我无法更改 switch 语句”是什么意思?如果有足够多的可能性,我会考虑使用字典。请注意,这主要是为了可读性和可维护性,而不是性能。使用字典,例如进行反向转换会更容易,因为您可以从相同的数据构造一个反向字典。

使用字典,它看起来像这样:

private static readonly Dictionary<string, EnumFactorType> _factorTypeMap =
new Dictionary<string, EnumFactorType>(StringComparer.InvariantCultureIgnoreCase)
{
    { "beta", EnumFactorType.BETA },
    { "bkp", EnumFactorType.BOOK_TO_PRICE },
    // etc. You can still use strings constants here instead of literals.
};

然后在你的方法中:

EnumFactorType factorType;
if (_factorTypeMap.TryGetValue(str, out factorType))
{
    e.FactorType = factorType;
}
else
{
    throw new Exception("Unexpected value, bla bla");
}

如果您确定该值存在,那就更简单了:

 e.FactorType = _factorTypeMap[str];

创建一个反向字典是单行的,这里显示为两行:)

Dictionary<EnumFactorType, string> _factorTypeReverseMap =
    _factorTypeMap.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);

【讨论】:

    【解决方案3】:

    开关中使用的字符串必须是常量,所以如果你声明一个常量而不是变量,你可以在开关中使用它:

    public const string BETA = "beta";
    

    如果您不希望字符串保持不变,以便在程序运行时更改它们,则不能使用开关。然后您可以使用Dictionary&lt;string, EnumFactorType&gt; 来查找值以获得与开关相似的性能。

    【讨论】:

    • 当编译器将其设为 const 时,如上所述,这样做是没有意义的。我们不需要创建 const,因为我们没有重用这个值。
    • @LCarter:当然没有意义,但它回答了问题。
    猜你喜欢
    • 1970-01-01
    • 2011-02-28
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多