【问题标题】:C# IF statements, and doing things very specifically from which is trueC# IF 语句,以及非常具体的做事,其中是正确的
【发布时间】:2012-07-18 17:01:33
【问题描述】:

所以,首先,我看过这样的帖子:How to find which condition is true without using if statement

这不是我所需要的,虽然这个想法是相关的,因为我希望它是更具可读性的代码。

我认为 Switch 是最好的选择,但让我解释一下。

我有这样的声明:

if (input == string.Empty || typeComboBox.Text == null)
{
    MessageBox.Show("Nothing to encrypt!", "Nothing Selected!");            
    return null;
}

所以这里的想法是我曾经把这个语句分成两个“IF”语句,这不是什么大不了的事,但为了可读性,以及我不断减少代码的努力,我想结合声明合二为一。

如果输入为空,我希望 MessageBox.Show 中的第一个参数出现,而不是第二个。

如果 typeComboBox.Text 为空,我希望出现第二个选项,而不是第一个。

如果它们都是真实的陈述,我希望它们都出现。

现在,我的目标是在不使用多个测试或方法的情况下完成这两项工作。基本上,我的意思是:如果我能找到哪个条件为真,并在同一个语句中输出结果数据,那将是理想的。

我认为开关是一种选择,但我还不太了解它们,但我认为这需要我根据此测试的结果做出决策方法,并将该结果发送给开关;这并不理想,因为我可以简单地有两个 if 语句和更少的代码。

有没有办法在一个语句中做到这一点?这个特定的程序没有必要,但我想知道未来。

谢谢!

【问题讨论】:

  • 最直接的方法是使用两个if 语句。那样做。 (如果您希望显示两个消息框,而不是一个带有串联消息的消息框。)假设 C# 实际上支持直通,我不认为带有直通的开关可以做您想做的事情。
  • 这就是我认为最终会发生的地方;我总是可以用两个 IF 语句对其进行测试,但是如果有/有什么方法可以使它成为一个结果可变的测试,我想知道!
  • @plast1K 您问题中的if 已经在执行两项测试,而不是一项。 (如果您查看生成的 IL,实际上它更接近四个测试。)

标签: c# if-statement minify


【解决方案1】:

我假设您从以下代码开始:

if (input == string.Empty)
{
    MessageBox.Show("Nothing to encrypt!");            
    return null;
}

if (typeComboBox.Text == null)
{
    MessageBox.Show("Nothing Selected!");            
    return null;
}

我认为这段代码没有任何问题,这可能是最易读的。它将根据需要执行尽可能多的测试,仅此而已。任何替代方案都会导致执行 更多 测试,即使您最终可能会使用更少的代码。例如:

if (input == string.Empty || typeComboBox.Text == null)
{
    MessageBox.Show((input == string.Empty) ? "Nothing to encrypt!" : "Nothing Selected!");
    return null;
}

代码行数更少,但在失败的情况下,将执行两到三个测试,而不是一两个。它也有点不那么简单。

简洁的代码很好,但是太简洁会变得更难维护。可读性介于冗长和简洁之间,在我看来,在这种情况下,更冗长的代码更具可读性。


另一种选择是考虑报告多个错误是合适的事实。为此,请尝试如下代码:

List<string> errors = new List<string>();

if (input == string.Empty)
{
    errors.Add("Nothing to encrypt.");
}

if (typeComboBox.Text == null)
{
    errors.Add("Nothing selected.");
}

if (errors.Count != 0)
{
    MessageBox.Show(string.Join(" ", errors.ToArray()));
    return null;
}

这比您的原始代码更冗长,但它允许报告所有相关的错误,而不是只报告遇到的第一个错误。

【讨论】:

  • 我不反对投反对票,但我会感谢任何这样做的人的评论,以便我知道如何改进我的答案。
  • 这是一个绝妙的答案,同时它也为我提供了简洁代码的精彩表示,我也在查看它,尽管我在理解它时也遇到了一些困难。我很欣赏澄清。如果我没记错的话,简洁的代码基本上是测试一个条件是否为真,如果是,则继续测试。在前者为真时,它针对单个参数进行测试,因为只有两个参数,如果它为假,逻辑上它使用与其他错误相关的正确响应,即使它没有“看到”?
  • 简洁的代码将测试是否满足任一失败条件。如果至少有一个,那么它将根据哪个条件失败显示一条消息(它将再执行一次测试)。 ?: 运算符是内联条件;如果a 为真,则表达式a ? b : c 将测试a 并计算为b,如果a 为假,则计算为c。换句话说,test-expression ? result-if-true : result-if-false.
【解决方案2】:

@millimoose 的评论是正确的;两个 if 语句对您的代码来说是最干净的。但是,如果您想将验证扩展到大量或建立此类验证的一般模式,则可以执行设置验证表之类的操作:

public class ValidationRule
{
    public ValidationRule(Func<bool> test, string errorMessage)
    {
        this.Test = test;
        this.ErrorMessage = errorMessage;
    }

    public Func<bool> Test { get; private set; }
    public string ErrorMessage { get; private set; }
}


var validationRules = new[] {
    new ValidationRule(() => input != string.Empty, "Nothing to encrypt!"),
    new ValidationRule(() => typeComboBox.Text != null, "Nothing Selected!")
};

有了这样的表格,你就可以有这样的代码:

var errors = validationRules.Where(r => !r.Test()).Select(r => r.ErrorMessage);
if (errors.Any())
{
    MessageBox.Show(string.Join(' ', errors));            
    return null;
}

但是,如果您只是在寻找适合您的两个条件的东西,那么这就是过度设计。

【讨论】:

    【解决方案3】:

    我会建议一个稍微不同的模式,它可能更具可读性:

    StringBuilder message = new StringBuilder();
    
    if (input == string.Empty) message.Append("Nothing to encrypt!\n");
    if (typeComboBox.Text == null) message.Append("Nothing selected!\n");
    // ... repeat as many times as desired ...
    
    if (message.Length > 0) {
        MessageBox.Show(message);
        return null;
    } else {
        // proceed with your code here
    }
    

    此代码的优点是它可以显示多条消息,如果多条消息是有效的。如果用户一次只能看到一条消息,如果他们必须返回,修复某些内容,点击提交,然后看到不同的错误消息,这可能会让他们感到沮丧。

    【讨论】:

    • 我可能会选择List&lt;string&gt;,因为这样可以减少添加分隔空格的麻烦。使用此代码的两条消息之间将没有空格。
    • 这确实是一个很好的答案,你对我的程序有了很多了解,因为我什至没有考虑考虑多个 MessageBox!感谢字符串生成器的提示。
    【解决方案4】:

    代码中没有办法让三个(看似)不同的操作由单个逻辑语句决定。如果您尝试将其分解为最简单的逻辑(不是在代码中,而只是在心理逻辑中)流程,您仍然会得到类似的结果:

    如果 A 为真,则执行 B 如果 C 为真,则执行 D 如果 A 和 C 都为真,则做 B 和 D

    这可以通过注意(如您所做的那样)每个条件实际上彼此独立来简化:

    如果 A 为真,则 B 总是完成 如果 C 为真,则 D 总是完成

    因此,在您的代码中,最简单的细分是

    if (input == string.empty)
    {
        // Do some stuff
    }
    
    if (typeComboBox.Text == null)
    {
        // Do some other stuff
    }
    

    现在,无需对任何一种方法都有一长串复杂的指令集 - 您可以通过将其作为一个简单的决策部分来简化代码的外观,该部分调用其他方法来完成工作:

    if (input == string.empty)
    {
        this.PrimeInputs(); // or something
    }
    
    if (typeComboBox.Text == null)
    {
        this.InitTextBoxes(); // or something
    }
    

    主要的是,这与逻辑 AND 和逻辑 OR 不同,因为您需要一种或另一种操作 - 在某些情况下,如果两种情况都为假,则不采取任何行动,如果两种情况都为真,则两种行动都需要。

    【讨论】:

      【解决方案5】:

      我不会说这比几个“if”语句更好,但它只是一个。

      var message = 
          ((input==string.Empty ? 
              "Nothing to encrypt! " : 
              "") +
          (typeComboBox.Text == null ?
              "Nothing Selected!" :
              "")).Trim();
      
      
      if (message != "") {
          MessageBox.Show(message);
          return null;
      }
      

      不过,一般来说,我喜欢使用条件运算符来构建产生单一结果的逻辑树,它比一堆嵌套的 if/else 子句要简洁得多。只要您正确缩进,我就会发现这样的结构具有高度的可读性和表现力。不幸的是,在这种情况下它并不理想,因为您的结果取决于操作数的组合。使用这种逻辑来构建字符串可能不是最好的主意,尽管它仍然可能是最简洁的选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 2017-01-07
        • 2019-07-23
        • 1970-01-01
        相关资源
        最近更新 更多