问题
I have this code where each part of the switch returns a value to ModeMessage2
. Is it possible using the new C# switch
expressions (or any other code optimization) to optimize the way this switch
works?
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;
}
回答1:
Your code is similar to the following, though if there are side effects of setting ModeMessage2
or the other properties then the order that things happen might matter in which case this is not technically 100% equivalent.
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);
回答2:
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);
}
回答3:
You should use a dictionary to do this --
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]);
This will be much faster than any switch statement and easier to maintain.
You could also use an array if that makes sense.
Note to commenters below: I'm making the following assumptions, which could be false in some cases but not in the general case. 1) the code is written in a way that the "allocation" only happens once for the lifetime of the code -- in this case if the map is used more than once, you get savings so that after N time the cost of allocation goes to 0. 2) We don't know the type of the key, comments that assume it is a string are making an assumption that might not be true. EVEN SO, any "fast" comparisons of strings is using a hash which is the same thing a dictionary uses to get it speed. 3) It is well known that the slowest thing you can do in programming is a branch. A dictionary (or array map) allow you to not have any branches, just a calculation to a memory location.
来源:https://stackoverflow.com/questions/58998500/is-there-a-way-for-switch-to-return-a-string-value-using-c-sharp-8-switch-expres