什么是完美的写作方式;返回“;在一种方法中
本文关键字:方法 一种 返回 完美 什么 方式 | 更新日期: 2023-09-27 18:20:26
我不喜欢方法有几个返回行。所以我用字符串result创建了一个返回值,在每个条件下我都写result=something。。。
但当我编写"try-catch"机制时,我必须设置公共字符串结果。因为,若我在try中返回一个结果,编译器将启动error,并表示并非所有代码都有返回值。如果我写result=string。在方法结束时清空,resharper说,这是不可访问的代码。这里有一个例子,这是我的问题;
"在方法中写入"return"的最佳方式是什么?"
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
设置为在发生异常时有意义的值。
如果你试图坚持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时遇到问题的原因。
一些建议,包括已接受答案的第一部分和原始问题,很有可能返回不正确的结果,尤其是在出现异常的情况下。
问题是,当您有一个单一的返回值时,对方法逻辑的微小更改将不可避免地导致原始方法编写器没有预料到的代码路径,并将导致返回变量在方法中多次设置错误或根本没有设置。
当然,有时您必须收集一个值以返回给调用者,然后在该值之后在方法中执行一些额外的任务,但总的来说,这应该是例外,而不是规则。
在追踪了太多由于希望有一个单一的返回值而引入的错误之后,我们的开发标准现在规定,除非绝对必要,否则将使用return
,并且必须在代码中彻底记录不这样做的原因,以及对后续修饰符的警告。
这种方法的另一个好处是,如果方法的逻辑被修改为新的代码路径在返回逻辑中造成"漏洞",编译器将自动通知您这一点。使用单个返回值需要开发人员直观地检查每个可能的代码路径,以验证是否没有遗漏任何内容。
最后,我们要求从异常处理程序中返回适当的默认值,而不是在异常之外有一个返回值。这样一来,在出现异常的情况下会发生什么就非常清楚了。
因此,在我们的环境中,您的代码将是:
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中,您可以依靠异常机制和finally
语句来处理资源(在Java 7中,还有"try with resources"特性)。
选择return
语句还有其他原因。一个是将变量标记为final的能力:因为编译器知道return
(或抛出)是方法的结束,所以可以更容易地插入final变量。最终变量——一旦你习惯了它们——真的可以让你更容易地阅读代码,并帮助你避免犯错误。
boolean someErrorCondition = true;
final int setSomething;
for (int i = 0; i < 8; i++) {
if (i == 7) {
setSomething = 11;
break;
}
if (someErrorCondition) {
return;
}
}
这不适用于您的方法,因为编译器会抱怨没有设置最终变量(这就是整个想法,没有进入无效状态)。
许多优秀的开发人员和语言设计师都选择了多个返回语句。我会紧急建议任何人不要朝另一个方向走。
如果出现异常,则不返回值。
多个返回语句使代码更容易理解。通过这种方式,您可以立即看到不同的方法返回点。相反,一个返回的"结果"字段会迫使您找到字段更改后的使用位置。这使得遵循该方法的自然流程变得更加困难。但无论如何,通常设计更多的是关于风格偏好。确保不要混淆两种方法。