我不喜欢方法有几条返回线。所以我用字符串结果创建了一个返回值 - 在每种情况下我都写了result = something ...
但是当我编写“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?
}
答案 0 :(得分:4)
你可以这样做:
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麻烦的原因。
答案 1 :(得分:2)
有些建议,包括接受答案的第一部分和原始问题,很有可能返回不正确的结果,尤其是在发生例外情况时。
问题,我们已经看到这种情况发生了很多次,当你有一个返回值时,对方法逻辑的微小改动总会导致通过代码的路径,这是原始方法编写者没有预料到的。将导致返回变量在方法中多次设置错误或根本未设置。
有些时候你必须收集一个返回调用者的值,然后在后面的方法中执行一些额外的任务,但总的来说应该是例外而不是规则。
在追踪过多因为希望获得单一回报价值而引入的错误之后,我们的开发标准现在要求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;
}
}
答案 2 :(得分:2)
所以你声称帮助你到达那个出口点的if
语句(或其他程序流程语句)本身并不是一个退出点?该控制语句与return
语句之间的唯一区别是return
语句实际上更明显,更易读,更易于维护且不易出错。此外,由于return语句可以在任何级别上运行,因此您可能会重复控制语句x次。
想要在结尾处使用return语句的唯一原因是资源处理 - 摆脱您在开始时声明的资源。这在C / C ++中更为常见(即使在C ++中,它也没有那么麻烦)。在Java中,您可以依赖异常机制和finally
语句来处理应有的资源(在Java 7中,“尝试使用资源”功能)。
还有其他理由选择return
语句。一个是最终标记变量的能力:因为编译器知道return
(或者抛出那个问题)是方法的结束,你可以更容易地插入最终变量。最终变量 - 一旦你习惯了它们 - 真的可以很容易地阅读代码并帮助你避免犯错误。
boolean someErrorCondition = true;
final int setSomething;
for (int i = 0; i < 8; i++) {
if (i == 7) {
setSomething = 11;
break;
}
if (someErrorCondition) {
return;
}
}
这不适用于您的方法,因为编译器会抱怨最终变量没有被设置(这是整个想法,而不是进入无效状态)。
众多优秀的开发人员和语言设计人员选择了多个返回语句。我会紧急建议任何人不要走向另一个方向。
答案 3 :(得分:0)
如果发生异常,则不返回值。
答案 4 :(得分:0)
多个return语句可以更轻松地遵循您的代码。这样您就可以立即看到不同的方法返回点。相反,返回“结果”字段会强制您查找字段在更改后的使用位置。这使得遵循该方法的自然流程变得更加困难。但无论如何,通常情绪更多的是关于风格偏好。确保不要混用两种方法。