仅使用'if-else'语句的'else'部分是否可以接受?

Joh*_*ski 21 c# conditional if-statement

有时,我觉得检查所有条件是否都是真的更容易,但是只处理"其他"情况.

我想我有时会觉得更容易知道某些东西是有效的,并假设所有其他情况都无效.

例如,假设我们只在出现问题时才真正关心:

object value = GetValueFromSomeAPIOrOtherMethod();

if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
    // All the conditions passed, but we don't actually do anything
}
else
{
    // Do my stuff here, like error handling
}
Run Code Online (Sandbox Code Playgroud)

或者我应该改变它:

object value = GetValueFromSomeAPIOrOtherMethod();

if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
    // Do my stuff here, like error handling
}
Run Code Online (Sandbox Code Playgroud)

或者(我觉得很难看):

object value = GetValueFromSomeAPIOrOtherMethod();

if(!((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop))))
{
    // Do my stuff here, like error handling
}
Run Code Online (Sandbox Code Playgroud)

Eri*_* J. 60

虽然对我来说很少见,但有时候我觉得用这种形式书写会在某些情况下产生最清晰的代码.寻找提供最清晰的表格.编译器不会关心,并且应该基本上(可能确切地)生成相同的代码.

但是,可能更清楚的是,定义一个在if()语句中赋值的布尔变量,然后将代码写为该变量的否定:

bool myCondition = (....);
if (!myCondition)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 对不起,我只是不买.它读作"好吧,如果这个条件成立,那么......什么都不做.*但*,如果它*不是真的那么,那么就这样做......"这比只说"如果这样"更具可读性条件不正确......"? (9认同)
  • @Jared:当我在阅读代码时,一个否定的复杂布尔条件是最不易读的,一个空的if块更易读,而用于保持评估条件的单独变量是最清晰的.看起来社区是按照前两个语句的顺序平均分配的.我可以说出我最不容易混淆的事情. (2认同)

Jar*_*Par 55

在else中使用带有语句的空if块是......只是糟糕的样式.对不起,这是我的一个小小的烦恼.它没有任何功能上的错误,只是让我的眼睛流血.

简单!输出if语句并将代码放在那里.恕我直言,它降低了噪音,使代码更具可读性.

  • 我不同意这些人.理解NOT的概念非常简单 (23认同)
  • 否定整个条件有时会使代码混淆阅读. (12认同)
  • 与英语相比是非常有效的.初级程序员在3年的时间内偶然发现了这一点,这样做就是为了理解首先是什么意思.表达越简单,维护越容易.同意JaredPar,可以简化表达式以增强可维护性.一个否定的,微不足道的布尔表达式并不难阅读,但是这个表达式有3个术语并且不是微不足道的. (5认同)
  • 这个概念很容易理解,但它总是很容易阅读?并不是的. (4认同)
  • @Ed:如果你是第一个编写复杂布尔条件的人,并且自你编写它以来不到几周,应该是小菜一碟.他们教你不要不在英语课上使用双重否定词是有原因的.它们比正面陈述的案件更令人困惑. (2认同)

Ste*_*esa 28

我应该先说这是我个人的偏好,但我发现自己通常会将验证逻辑从代码中拉出来并进入自己的验证函数.那时,您的代码变得更加"整洁",只需说:

if(!ValidateAPIValue(value))
Run Code Online (Sandbox Code Playgroud)

在我看来,这似乎更简洁,更容易理解.


Geo*_*ips 9

仅使用else部分是不可接受的.你不需要去应用De-Morgan的规则,而不是整个表达.也就是说,从去if (cond)if (!(cond)).

  • !Eric J.:除非你认为否定本身很复杂,否则它并不复杂.如果否定很复杂,那么请等到*binary*运算符! (7认同)
  • 复杂的否定导致错误,错误导致错误,错误导致痛苦. (3认同)

Jor*_*ren 9

我认为这是完全不可接受的.

唯一的理由是避免表达式周围的单个否定和括号.我同意你的例子中的表达是可怕的,但它们开始时是不可接受的错综复杂的!将表达式划分为可接受的清晰度部分,将它们存储到布尔值中(或者将它们放在它们之外),并将它们组合起来以形成if语句条件.

我经常使用的一个类似设计是提前退出.我不写这样的代码:

if (validityCheck1)
{
    if (validityCheck2)
    {
        // Do lots and lots of things
    }
    else
    {
        // Throw some exception, return something, or do some other simple cleanup/logic (version 2)
    }
}
else
{
    // Throw some exception, return something, or do some other simple cleanup/logic. (version 1)
}
Run Code Online (Sandbox Code Playgroud)

相反,我写这个:

if (!validityCheck1)
{
    // Throw some exception, return false, or do some other simple logic. (version 1)
}

if (!validityCheck2)
{
    // Throw some exception, return false, or do some other simple logic. (version 2)
}

// Do lots and lots of things
Run Code Online (Sandbox Code Playgroud)

这有两个好处:

  1. 只有少数输入案例无效,并且处理起来很简单.它们应该立即处理,以便我们尽快将它们从心智模型中删除,并完全专注于重要的逻辑.特别是当嵌套的if语句中存在多个有效性检查时.

  2. 处理有效案例的代码块通常是方法的最大部分,并包含自己的嵌套块.如果这个代码块本身不在if语句中嵌套(可能多次),那就不那么混乱了.

因此代码更易读,更容易推理.