繁体   English   中英

我怎样才能摆脱这些 else if 语句并使代码看起来更好?

[英]How can I get rid of these else if statements and make the code look better?

我有这个 c# 代码

progressBar1.Increment(1);
if (progressBar1.Value > 5 && progressBar1.Value < 10)
{
  label1.Text = "Some text...";
  timer1.Stop();
  timer1.Start();
  timer1.Interval = 1000;
}
else if (progressBar1.Value > 10 && progressBar1.Value < 15)
{
  label1.Text = "Some text 2...";
  timer1.Interval = 250;
}
else if (progressBar1.Value > 15 && progressBar1.Value < 30)
{
  label1.Text = "Some text 3...";
}
else if (progressBar1.Value > 30 && progressBar1.Value < progressBar1.Maximum)
{
  label1.Text = "Some text 4...";
  timer1.Interval = 100;
}
else if (progressBar1.Value == progressBar1.Maximum)
{
  timer1.Stop();
  const string message = "Some cool popup message";
  const string caption = "Test";
  MessageBox.Show(message, caption, MessageBoxButtons.OK);
  Close();
}

我确定这段代码很糟糕,我不是真正的程序员,我只是尝试创建一些有趣的应用程序。 我怎样才能摆脱这些很长的 else if 语句并用更好的东西替换它? 我一直在寻找答案和提示,但没有一个对我有帮助。

我能想到的两种方法:

简化条件并使用continue更改流程我在这里假设您处于forwhile循环中

progressBar1.Increment(1);
if (progressBar1.Value < 5) continue;
if (progressBar1.Value < 10)
{
  label1.Text = "Some text...";
  timer1.Stop();
  timer1.Start();
  timer1.Interval = 1000;
  continue;
}
if (progressBar1.Value < 15)
{
  label1.Text = "Some text 2...";
  timer1.Interval = 250;
  continue;
}
if (progressBar1.Value < 30)
{
  label1.Text = "Some text 3...";
  continue;
}
if (progressBar1.Value < progressBar1.Maximum)
{
  label1.Text = "Some text 4...";
  timer1.Interval = 100;
  continue;
}

  timer1.Stop();
  const string message = "Some cool popup message";
  const string caption = "Test";
  MessageBox.Show(message, caption, MessageBoxButtons.OK);
  Close();

如果不在循环中,则删除 continue 并重新添加 else 语句和最大条件if 该代码只会输入 if/else 情况之一。

为了进一步研究,您可以提取到一个函数,但我需要您的整个示例来重构它。

甚至进一步的研究可能会导致您进入适合您的情况的状态模式,但这太过分了。

在 C#9(目前仅在预览版中可用)中,您将能够像这样使用关系模式匹配

progressBar1.Increment(1);

switch (progressBar1.Value)
{
    case > 5 and < 10:
        label1.Text = "Some text...";
        timer1.Stop();
        timer1.Start();
        timer1.Interval = 1000;
        break;
        
    case > 10 and < 15:
        label1.Text     = "Some text 2...";
        timer1.Interval = 250;
        break;
        
    case > 15 and < 30:
        label1.Text = "Some text 3...";
        break;
        
    case > 30 and < progressBar1.Maximum:
        label1.Text     = "Some text 4...";
        timer1.Interval = 100;
        break;
        
    case progressBar1.Maximum:
        timer1.Stop();
        const string message = "Some cool popup message";
        const string caption = "Test";
        MessageBox.Show(message, caption, MessageBoxButtons.OK);
        Close();
        break;
}

这使得如何细分范围更加清晰。 (据我所知,C# 9 应该在今年 11 月左右发布。)

你的代码还不错(除了使用<而不是<= < 等的一些潜在差距。很清楚意图是什么,如果它有效;完全可以接受。

不要陷入更少代码就是更好代码的陷阱。 查看一些建议的“改进”。 他们做什么很明显,还是你必须花时间思考实际的逻辑是什么。 我已经看到太多嵌套的三元表达式,当试图破译时(更不用说试图调试表达式的一部分),当一个嵌套的if会做完全相同的事情并且更容易理解时,调试,和维护。

您有 5 个潜在状态,它们之间的重叠(效果方面)很少。 我会说这是完全可以接受的 5 个if语句的使用。 如果它们都是“相等”的情况而不是范围,并且每个都只是设置相同的变量,那么也许像Dictionary这样更高级的东西可能会有用,但这里不是这种情况。

由于您是初学者,而且我要展示的内容有点复杂,我强烈建议您查看三元条件运算符,因为这就是我要在这里展示的内容。

这是一段代码:

        Console.WriteLine(text);
        text = (!(value > 10 && value < 15)) ? "Some text..." : "";

        Console.WriteLine(text);
        text = (!(value > 15 && value < 30)) ? "Some text 2..." : "";

        Console.WriteLine(text);
        text = (!(value > 30 && value < maximum)) ? "Some text 3..." : "";

        Console.WriteLine(text);
        text = (!(value == maximum)) ? "Some text 4..." : "";

        Console.WriteLine(text);
        text = "Some cool message";

        Console.WriteLine(text);

现在,不要害怕这个,我会解释的。

所以这些单行是三元条件。 它们基本上是常规的 if/else 条件,但作为一行。 它们非常好,可以使您的代码更简洁,而且还可以给它一个“花哨”的外观。

您应该注意到我没有使用 WinForms 项目,而是使用控制台项目,以便于测试。

如您所见,没有第一个条件,即value > 5 && value < 10 那只是因为我们不需要它。

到最后你也可能会感到困惑。 如您所见,最终消息不是在条件下,而是在value == maximum条件之后。 为什么? 嗯,那只是因为它是如何工作的。 如果你对我说的有一点不明白,你真的应该看看我上面发的文章。

无论如何,这是传说:

value是 ProgressBar 的值,所以这里是progressBar1.Value

maximum是 ProgressBar 的最大值,所以这里是progressBar1.Maximum

现在你只有几个案例,所以我几乎没有什么不同。 如果您有很多案例,查找表可以使它变得容易得多。

伪代码:

struct Case {
  int Min, Max; // inclusive
  String txt; // if not empty
  int TimerValue; // set if greater than zero.
  Func ToCall; // null or lampda
};

Case cases { 
  { 6, 9, "Text1", 1000, { timer1.Stop(); timer1.Start(); } }, 
  { 11, 14, "Text2, 250, {}},
  etc.
}
ASSERT(is_sorted(cases)); // so we don't mess up the order.

auto res = BinarySearch(value, cases);
if (!res) continue;
Execute(res);

这在很多情况下可以节省一些工作。

这是您可以查找的一些示例。

switch (value)
{
     case var expression when value < 0:
         //some code
         break; 

     case var expression when (value >= 0 && value < 5):
         //some code
         break;

     default:
         //some code
         break;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM