C#-写入方法块

C#-写入方法块,c#,methods,C#,Methods,这是关于方法块结构的一般问题。考虑到下面的两个备选方案,有人对设计方法的更好方法有什么看法吗 private void Method1() { if (!A) { return; } if (!B) { return; } if (!C) { return; } // DO WORK....... return; } private void Meth

这是关于方法块结构的一般问题。考虑到下面的两个备选方案,有人对设计方法的更好方法有什么看法吗

private void Method1()
{
    if (!A)
    {
        return;
    }

    if (!B)
    {
        return;
    }

    if (!C)
    {
        return;
    }

    // DO WORK.......

    return;
}

private void Method2()
{
    if (A)
    {
        if (B)
        {
            if (C)
            {
                // DO WORK.......

                return;
            }
        }
    }

    return;
}
我更喜欢方法1,“提前退出”方法。在我看来,这更清楚。我真的尽量避免很多嵌套的“if”语句

另外,在void方法中不能返回“null:)

个人偏好

我想我应该这样做:

if(A && B && C) {
   // Do Work...
   return;
}

第一种方法是有争议的-个人偏好有多个条件或一个或多个条件


但是第二种方法不好,不好,不好。单一方法中的多级缩进只会带来bug——可维护性和可读性大大降低。这是众所周知的

您正在用标签交换返回声明。你打电话


个人而言,我喜欢C++ 2,其中处理自动释放对象(例如CCOPTR、AutoPtr等),但C语言中不需要。我倾向于使用C#的第一个例子,因为你有垃圾收集,你可以不用担心确保在早期退出时清除所有东西。

首先,void方法不能返回值,但假设你返回int

private int? method3 ()
{
  int? retVal;
  if (A && B && C)
  {
    // do work
    retVal = x;
  }
  return retVal;
}
那么:

if(A && B && C)
{
     //Do work
}

return;


我会站出来说,这两种可能都是代码气味。我不认为应该教条式地坚持旧的“只有一个出口”的编码哲学,但方法中的许多出口点可能与嵌套很深的IF语句一样成为维护的噩梦


当看到其中任何一个时,重构灯都应该熄灭。

我倾向于尝试并始终使用一些看起来相当容易阅读的东西:

private void Method1()
{
    if (!A ||
        !B ||
        !C)
    {
        return;
    }
    else if(D)
    {
        return y;
    }

    // DO WORK...

    return X;
}

但正如其他人所提到的,这完全是个人优先权,除非您的工作场所指定了高于其他标准的一个标准。

前提条件逻辑可以分解为单独的方法:

private Boolean CanContinue()
{
  return A && B && C;
}

private void Method1()
{
  if (CanContinue())
  {
    // Do work...
  }
}
这有几个优点:

  • 前置条件逻辑是单元测试的潜在候选者
  • 逻辑可以重复使用
  • 当逻辑很复杂时,我认为如果将其封装在自己的方法中,则更容易理解和维护

在完成任何有用的工作之前,以三个if语句开头的方法具有明显的臭味

如果您的方法以一串If语句开始,请暂停片刻,重新计算因子,然后继续


也许一个
开关
语句比一串if语句更合适。

此外,您应该在第1部分中只说“return”而不是“return null”。如果第一种方法有争议,您会怎么做?同意!嵌套块是不好的,因为遵循结构和逻辑很难。我不认为它很难或“可读性较差”。我在(C++)商店工作过,在那里两者都是必需的样式,我发现只需要大约两周的时间就可以适应样式的更改。一般来说,如果您基于正确的理由始终如一地应用三角代码,那么三角代码也同样具有可读性和可维护性。但我不认为这些原因中的任何一个适用于C#。@jeffamaphone,因为这个问题完全是关于C#,对于我们这些不应该在精神上一次跟踪超过几个缩进级别的白痴来说,最好谨慎行事。抱歉不同意,Jeff。“三角形”代码迅速转变为“山脉”代码,因为每个if都得到了else-if和else子句的对应项,在某些情况下,弄清楚特定代码段在何种条件下执行是不可能的。最好将条件变小,最好重构成单独的方法。如果嵌套太深,可以编写三角代码并调用辅助函数。我的经验法则是,如果你在一个函数中做了6次,你的函数就太复杂了。YMMV.+1用于提前退出。这种方法有帮助的一个更好的例子是,当您得到一个对象,并且需要将一系列属性方法传递给执行操作所需的其他对象(foo.Bar.ReadBlah().Orders和we need Orders)。在这个过程中,您可能会得到一个空值,因此您需要保释,执行这些操作可能会很昂贵。在这种情况下,这比下面的示例要好得多,在下面的示例中,尝试使用多个&&运算符将其包装在一个条件中。当您可以提前中止并忘记该条件时,为什么要将整个例程包装在一个额外的缩进级别中?有时您真正想要的是:GetA()、if(!A){return}、GetB()等等。。。所以你不能只是检查它的存在。if语句之间存在隐含的函数调用。我想。否则,是的,这个讨论是没有意义的,你的建议是最好的解决方案。因为它比三次缩进要好。;-)我从来没有说过我会那样做,我只是给出一个建议。在序言中,很多退出点都很好。在这里,我们要确保我们有足够的信息来做我们正在做的任何事情。一旦我们通过了初始化,我同意:多次返回是个坏消息。@jeffamaphone:我想我更倾向于从参数检查的角度来考虑初始化。抛出异常可能会破坏控件,但我理解您的意思。我有一些方法可以执行4到5次检查,这可能会导致抛出异常,在这种情况下,尝试嵌套这些异常会很糟糕!请注意,您的实现并不等同于发布的实现,因为只有当一个和!B&!Csilky:是的,但是他在特定的地方有“//做工作”,而且我认为问题的实质更多的是关于风格,而不是具体的问题。你可以在void方法中使用return关键字立即返回。我知道这一点。在void方法中,不能返回值。这个问题最初是在返回一个值时提出的。
private Boolean CanContinue()
{
  return A && B && C;
}

private void Method1()
{
  if (CanContinue())
  {
    // Do work...
  }
}