在方法中编写“返回”的完美方式是什么?

我不喜欢方法有几条返回线。 所以我用字符串结果创建了一个返回值 – 在每种情况下我都写了结果=某事……

但是当我编写“try-catch”机制时,我必须设置公共字符串结果 。 因为,如果我在try中返回一个结果,编译器将启动错误,并说并非所有代码都有返回值。 如果我将result = string.Empty写入方法的结尾,resharper说,它是无法访问的代码。 所以,这里有一个例子,这是我的问题;

“在一种方法中写”回归“的完美方式是什么?”

public static string PingThatAddress(string hostAddress) { try { Ping ping = new Ping(); PingReply pingreply = ping.Send(hostAddress); string result; if (pingreply != null && pingreply.Status.ToString() != "TimedOut") { result = "Address: " + pingreply.Address + "\r" + "Roundtrip Time: " + pingreply.RoundtripTime + "\r" + "TTL (Time To Live): " + pingreply.Options.Ttl + "\r" + "Buffer Size: " + pingreply.Buffer.Length + "\r"; } else { result = string.Empty; } return result; } catch (Exception pingError) { Debug.Fail(pingError.Message + " " + pingError); } //compiler error: THERE IS NO RETURN VALUE here? } 

你可以这样做:

 public static string PingThatAddress(string hostAddress) { string result = string.Empty; try { Ping ping = new Ping(); PingReply pingreply = ping.Send(hostAddress); if (pingreply != null && pingreply.Status.ToString() != "TimedOut") { result = "Address: " + pingreply.Address + "\r" + "Roundtrip Time: " + pingreply.RoundtripTime + "\r" + "TTL (Time To Live): " + pingreply.Options.Ttl + "\r" + "Buffer Size: " + pingreply.Buffer.Length + "\r"; } } catch (Exception pingError) { Debug.Fail(pingError.Message + " " + pingError); } return result; } 

然后确保将result设置为在exception情况下有意义的内容。

如果你想坚持Resharper警告你的事情,那就这样做吧:

 public static string PingThatAddress(string hostAddress) { try { Ping ping = new Ping(); PingReply pingreply = ping.Send(hostAddress); string result = string.Empty; if (pingreply != null && pingreply.Status.ToString() != "TimedOut") { result = "Address: " + pingreply.Address + "\r" + "Roundtrip Time: " + pingreply.RoundtripTime + "\r" + "TTL (Time To Live): " + pingreply.Options.Ttl + "\r" + "Buffer Size: " + pingreply.Buffer.Length + "\r"; } return result; } catch (Exception pingError) { Debug.Fail(pingError.Message + " " + pingError); } return string.Empty; } 

你不能在这里有两种方式:你的人工标准没有多个return语句可能是导致你遇到Resharper麻烦的原因。

一些建议,包括接受答案的第一部分和原始问题,很有可能返回不正确的结果,特别是在发生例外情况时。

问题,我们已经看到过多次这样的事情,就是当你有一个返回值时,对方法逻辑的微小改动总会导致原始方法编写者没有预料到的代码路径,并导致返回变量在方法中多次设置错误或根本没有设置。

肯定有时候你必须收集返回调用者的值,然后在后面的方法中执行一些额外的任务,但总的来说应该是exception而不是规则。

在追踪了由于希望获得单一返回值而引入的太多错误之后,我们的开发标准现在规定除非绝对必要,否则将使用return并且必须在代码中详细记录不这样做的原因以及警告用于后续修饰符。

这种方法的另一个好处是,如果方法的逻辑被修改为新的代码路径在返回逻辑中导致“漏洞”,则编译器将自动通知您。 使用单个返回值要求开发人员可视地检查每个可能的代码路径,以validation没有遗漏任何内容。

最后,我们要求在exception处理程序中返回适当的默认值,而不是在exception之外返回值。 这样就可以清楚地知道在发生exception时会发生什么。

所以在我们的环境中,您的代码将是:

 public static string PingThatAddress(string hostAddress) { try { Ping ping = new Ping(); PingReply pingreply = ping.Send(hostAddress); if (pingreply != null && pingreply.Status.ToString() != "TimedOut") { return "Address: " + pingreply.Address + "\r" + "Roundtrip Time: " + pingreply.RoundtripTime + "\r" + "TTL (Time To Live): " + pingreply.Options.Ttl + "\r" + "Buffer Size: " + pingreply.Buffer.Length + "\r"; } else { return string.Empty; } } catch (Exception pingError) { Debug.Fail(pingError.Message + " " + pingError); return string.Empty; } } 

所以你声称帮助你到达那个出口点if语句(或其他程序流语句) 本身并不是一个退出点 ? 该控制语句和return语句之间的唯一区别是return语句实际上更可见,更易读,更易于维护且更不容易出错。 此外,由于return语句可以在任何级别上运行,因此您可能会重复控制语句x次。

想要在最后获得return语句的唯一原因是资源处理 – 摆脱您在开始时声明的资源。 这在C / C ++中更为常见(即使在C ++中,它也没有那么麻烦)。 在Java中,您可以依赖exception机制和finally语句来处理资源(在Java 7中,“尝试使用资源”function)。

还有其他理由选择return语句。 一个是最终标记变量的能力:因为编译器知道return (或者抛出这个问题)是方法的结束,你可以更容易地插入最终变量。 最终变量 – 一旦你习惯了它们 – 真的可以很容易地阅读代码并帮助你避免犯错误。

  boolean someErrorCondition = true; final int setSomething; for (int i = 0; i < 8; i++) { if (i == 7) { setSomething = 11; break; } if (someErrorCondition) { return; } } 

这不适用于您的方法,因为编译器会抱怨最终变量未被设置(这是整个想法,而不是进入无效状态)。

许多优秀的开发人员和语言设计人员选择了多个返回语句。 我会紧急建议任何人反对向另一个方向前进。

如果发生exception,则不返回值。

多个return语句使您可以更轻松地遵循代码。 这样您就可以立即看到不同的方法返回点。 相反,返回“结果”字段会强制您查找字段在更改后的使用位置。 这使得遵循该方法的自然流程变得更加困难。 但无论如何,通常情绪更多的是关于风格偏好。 确保不要混用两种方法。