[英]How to refactor these switch cases to handle user choice in natural language?
我正在写几个嵌套的 switch 语句,在某些地方有很多情况。
我试图找出一种方法来创建一个案例列表,然后在以后的 switch 语句中引用。
有没有办法做到这一点?
它肯定会清理我的代码。
例如,对于“是”的回答,我有四个不同的案例。
我正在寻找一种方法将这四种情况存储在一个变量中,并在每次我想在开关中使用它们时调用该变量。
Console.Write("\nWere you feeling exhausted? ");
response = Console.ReadLine().ToLower();
Console.Clear();
switch (response)
{
case "yes":
case "y":
case "yep":
case "yeah":
{
goto ThreeTwo;
}
case "no":
case "n":
case "nope":
case "nah":
一种简洁明了的方法是首先声明一个enum
来表示答案值。 它将需要“是”、“否”和“未定义”(后者表示既不是“是”也不是“否”的答案):
public enum YesOrNo
{
Undefined,
Yes,
No
}
然后您可以将是/否检测逻辑包装在 class 中。有很多方法可以做到这一点; 这是一个简单的方法(您可以改用字典,但是对于如此少量的字符串,它并不是真正必要的,我试图使它尽可能简单):
public static class YesOrNoDetector
{
static readonly string[] _yesAnswers = { "yes", "y", "yep", "yeah", "affirmative" };
static readonly string[] _noAnswers = { "no", "n", "nah", "nope", "negative" };
public static YesOrNo Detect(string answer)
{
if (_yesAnswers.Contains(answer.ToLower()))
return YesOrNo.Yes;
if (_noAnswers.Contains(answer.ToLower()))
return YesOrNo.No;
return YesOrNo.Undefined;
}
}
(请注意它如何通过在比较之前将字符串转换为小写来处理大写答案。)
然后你的原始代码变成这样:
switch (YesOrNoDetector.Detect(response))
{
case YesOrNo.Yes:
{
goto ThreeTwo; // Please get rid of this goto!
}
case YesOrNo.No:
{
// Handle "No".
break;
}
case YesOrNo.Undefined:
{
// Handle incorrect answer.
break;
}
}
有这个枚举:
public enum Answers
{
Other,
Yes,
No
}
可以添加任何预期的可能性。
还可以为各种用例创建多个枚举。
此处Other
表示未定义、未预测、未知等。
我们可以定义这个分配/分配/调度表:
using System;
using System.Collections.Generic;
readonly Dictionary<Answers, List<string>> AcceptedAnswers
= new Dictionary<Answers, List<string>>
{
{ Answers.Yes, new List<string> { "yes", "y", "yep", "yeah" } },
{ Answers.No, new List<string> { "no", "n", "nope", "nah" } }
};
因此我们可以轻松地为每个枚举值定义同义词。
我们将通过定义此验证方法来使用它:
Answers GetAnswer(string input)
{
foreach ( Answers item in Enum.GetValues(typeof(Answers)) )
if ( AcceptedAnswers.ContainsKey(item) )
if ( AcceptedAnswers[item].Contains(input) )
return item;
return Answers.Other;
}
测试
Console.WriteLine("Do you agree?");
var answer = GetAnswer(Console.ReadLine());
Console.WriteLine();
Console.WriteLine($"Your answer is: {answer}.");
Output
Do you agree?
yep
Your answer is: Yes.
高级用法
bool retry;
do
{
retry = false;
Console.WriteLine("Do you agree?");
var answer = GetAnswer(Console.ReadLine());
Console.WriteLine();
Console.WriteLine($"Your answer is: {answer}.");
switch ( answer )
{
case Answers.Yes:
// ...
break;
case Answers.No:
// ...
break;
default:
Console.WriteLine();
Console.WriteLine("I don't understand :(");
Console.WriteLine();
retry = true;
break;
}
}
while ( retry );
Do you agree?
I don't know
Your answer is: Other.
I don't understand :(
Do you agree?
yeah
Your answer is: Yes.
每个世纪请不要多次使用 goto。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.