是否有一种方法可以使用C#8开关表达式返回字符串值?

问题描述 投票:0回答:4

我有此代码,其中开关的每个部分都将一个值返回到ModeMessage2。是否可以使用新的C#switch表达式(或任何其他代码优化)来优化此switch的工作方式?

switch (Settings.Mode)
{
    case MO.Learn:
        ModeMessage2 =
            "Use this mode when you are first learning the phrases and their meanings.";
        if (Settings.Cc == CC.H)
        {
            Settings.Cc = CC.JLPT5;
            App.cardSetWithWordCount = null;
            App.DB.RemoveSelected();
        }
        break;
    case MO.Practice:
        ModeMessage2 =
             "Use this mode to help you memorize the phrases and their meanings.";
        if (Settings.Cc == CC.H)
        {
            Settings.Cc = CC.JLPT5;
            App.cardSetWithWordCount = null;
            App.DB.RemoveSelected();
        }
        break;
    case MO.Quiz:
        if (Settings.Cc == CC.H)
        {
            Settings.Cc = CC.JLPT5;
            App.cardSetWithWordCount = null;
            App.DB.RemoveSelected();
        }
        App.DB.UpdSet(SET.Adp, false);
        ModeMessage2 =
            "Use this mode to run a self marked test.";
        break;
}
c# switch-statement c#-8.0 switch-expression
4个回答
1
投票

此代码有点棘手,因为它包含带有副作用的整个块。也许您可以使用switch表达式生成消息在执行副作用之前决定要做什么。

无法在枚举上创建详尽的switch表达式,因此需要一个默认子句。在将来的C#版本中可能会更改

var (msg,isCC,upd) = Settings.Mode switch {
    case MO.Learn => ("Use this mode when you are first learning the phrases and their meanings.",
                      Settings.Cc == CC.H,
                      false),
    case MO.Practice => ("Use this mode to help you memorize the phrases and their meanings.",
                      Settings.Cc == CC.H,
                      false),
    case MO.Quiz => ("Use this mode to run a self marked test.",
                      Settings.Cc == CC.H,
                      true);
    _ => default;
}

if (msg is string) {
    ModeMessage2=msg;
}
if (isCC)
{
   Settings.Cc = CC.JLPT5;
   App.cardSetWithWordCount = null;
   App.DB.RemoveSelected();
}
if (upd)
{
    App.DB.UpdSet(SET.Adp, false);
}

默认情况下将导致(null,false,false)值,这意味着如果没有匹配项,则所有if都会失败。

如果您不介意在不匹配的情况下将ModeMessage2设置为某些默认值,则可以使用

(ModeMessage2 ,bool isCC,bool upd) = Settings.Mode switch {
    case MO.Learn    => ( learnMessage,
                          Settings.Cc == CC.H,
                          false),
    case MO.Practice => ( practiceMessage,
                          Settings.Cc == CC.H,
                          false),
    case MO.Quiz     => ( quizMessage,
                          Settings.Cc == CC.H,
                          true);
    _ => ("",false,false);
}

并摆脱一个if


0
投票
var modeMessage2 = Settings.Mode switch
{
    MO.Learn => "Use this mode when you are first learning the phrases and their meanings.",
    MO.Practice => "Use this mode to help you memorize the phrases and their meanings.",
    MO.Quiz => "Use this mode to run a self marked test."
}

if (Settings.Cc == CC.H)
{
    Settings.Cc = CC.JLPT5;
    App.cardSetWithWordCount = null;
    App.DB.RemoveSelected();
}

if (Settings.Mode == MO.Quiz) {
    App.DB.UpdSet(SET.Adp, false);
}


0
投票

您的代码类似于以下内容,但是如果设置ModeMessage2或其他属性有副作用,则事情发生的顺序可能很重要,在这种情况下,从技术上讲,这不是100%等效的。

IList<MO> specialModes = new[] { MO.Learn, MO.Practice, MO.Quiz };

if (specialModes.Contains(Settings.Mode) && Settings.Cc == CC.H) {
   Settings.Cc = CC.JLPT5;
   App.cardSetWithWordCount = null;
   App.DB.RemoveSelected();
}

ModeMessage2 = Settings.Mode switch {
   MO.Learn => "Use this mode when you are first learning the phrases and their meanings.",
   MO.Practice => "Use this mode to help you memorize the phrases and their meanings.",
   MO.Quiz => "Use this mode to run a self marked test.",
   _ => "Unknown mode value" // or throw
};

if (Settings.Mode == MO.Quiz)
   App.DB.UpdSet(SET.Adp, false);

0
投票

您应该使用字典来完成-

 Dictionary<TypeOf(Settings.Mode), string> map = new Dictionary<TypeOf(Settings.Mode), string>();

 map.Add(MO.Learn,"Use this mode when you are first learning the phrases and their meanings.");
 map.Add(MO.Practice,"Use this mode to help you memorize the phrases and their meanings.");
 map.Add(MO.Quiz,"Use this mode to run a self marked test.");


 ModeMessage2 = map[Settings.mode]);

这将比任何switch语句都快得多,并且更易于维护。

也可以使用数组。


下面的评论者注意:我正在做以下假设,在某些情况下可能是错误的,但在一般情况下可能不是。 1)以这样的方式编写代码:在代码的整个生命周期中,“分配”仅发生一次-在这种情况下,如果多次使用地图,您将获得节省,因此在N次分配之后到0。2)我们不知道键的类型,假设它是字符串的注释正在作出可能不正确的假设。即使如此,字符串的任何“快速”比较都使用哈希,这与字典用来提高速度的方法相同。 3)众所周知,编程中最慢的事情是分支。字典(或数组映射)允许您不具有任何分支,而仅是对内存位置的计算。

© www.soinside.com 2019 - 2024. All rights reserved.