0

所以,首先,我看过这样的帖子:如何在不使用 if 语句的情况下找到哪个条件为真

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

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

我有这样的声明:

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

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

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

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

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

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

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

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

谢谢!

4

5 回答 5

5

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

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;
}

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

于 2012-07-18T17:08:00.163 回答
1

@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;
}

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

于 2012-07-18T17:15:00.900 回答
0

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

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
}

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

于 2012-07-18T17:08:25.563 回答
0

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

var message = 
    ((input==string.Empty ? 
        "Nothing to encrypt! " : 
        "") +
    (typeComboBox.Text == null ?
        "Nothing Selected!" :
        "")).Trim();


if (message != "") {
    MessageBox.Show(message);
    return null;
}

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

于 2012-07-18T17:09:09.387 回答
0

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

如果 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 不同,因为您需要一个动作或另一个动作 - 在某些情况下,如果两种情况都为假,则不采取任何行动,如果两种情况都为真,则两种行动都需要。

于 2012-07-18T17:11:54.417 回答