“return”的正确写法是什么?在一个方法中

发布于 2024-12-27 07:06:44 字数 1246 浏览 3 评论 0原文

我不喜欢有多个返回行的方法。因此,我创建了一个带有字符串结果的返回值 - 在每种情况下我都写 result = some...

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

“在方法中编写“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?
    }

I don't like methods have several return lines. So I created a return value with string result - and in every condition I write result = something...

But when I write "try-catch" mechanism, I have to set public string result. Because, if I return a result in try, compiler will launch error, and says not all codes have return value. If I write result = string.Empty to end of the method, resharper says, it's not reachable code. So, here an example, and here is my question;

"What is the perfect way to write "return" in a method ?"

    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?
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

温折酒 2025-01-03 07:06:44

您可以这样做:

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 时遇到麻烦。

You could do it like this instead:

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;
}

Then just make sure result is set to something that makes sense in the case of an exception.

If you are trying to stick with what Resharper is warning you about, do it this way:

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;
}

You can not have things both ways here: Your artificial standard not to have multiple return statements is probably what is causing you to have trouble with Resharper.

辞别 2025-01-03 07:06:44

一些建议(包括已接受答案的第一部分和原始问题)很可能返回不正确的结果,特别是在发生异常的情况下。

问题是,我们已经多次看到这种情况发生,当您有一个返回值时,对方法逻辑的微小更改将不可避免地导致原始方法编写者没有预料到的代码路径,并会导致返回变量在方法中多次被错误设置或根本没有设置。

确实有时您必须收集一个值以返回给调用者,然后在随后的方法中执行一些附加任务,但总的来说这应该是例外而不是规则。

在追踪到太多由于希望拥有单一返回值而引入的错误之后,我们的开发标准现在规定,除非绝对必要,否则将使用 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;
    }
}

Some of the suggestions, including the first part of the accepted answer, and the original question have a strong potential to return incorrect results especially in the event of an exception.

The problem, and we have seen this happen numerous times, is that when you have a single return value, minor changes to the method's logic will invariably result in a path through the code that was not anticipated by the original method writer and will result in either the return variable incorrectly being set multiple times in the method or not set at all.

There are definitely times when you have to collect a value for returning to the caller and then perform some additional tasks in the method subsequent to that, but by and large that should be the exception rather than the rule.

After tracking down far too many bugs that were introduced by the desire to have a single return value, our development standards now dictate that return will be used unless absolutely necessary and the reason for not doing so must be thoroughly documented in the code along with warnings for subsequent modifiers.

The added benefit of this approach is that if the logic of the method is modified in such a way that the new code path causes a "hole" in the return logic, you will be automatically notified about this by the compiler. Using a single return value requires the developer to visually inspect every possible code path in order to verify that nothing was missed.

Finally, rather than having a return value outside of the exception, we require that the appropriate default value be returned from within the exception handler. This way it is crystal clear as to what will happen in the event of an exception.

So in our environment, your code would be:

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;
    }
}
如若梦似彩虹 2025-01-03 07:06:44

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

希望在最后有 return 语句的唯一原因是资源处理 - 摆脱您在开始时声明的资源。这在 C/C++ 中更为常见(即使在 C++ 中,如果没有它也会变得不那么麻烦)。在Java中,您可以依靠异常机制和finally语句来按应有的方式处理资源(在Java 7中,“尝试使用资源”功能)。

选择 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;
      }
  }

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

许多优秀的开发人员和语言设计人员都选择了多重返回语句。我强烈建议任何人不要走相反的方向。

So you are claiming that the if statement (or other program flow statement) which is helping you get to that exit point, isn't actually an exit point by itself? The only difference between that control statement and the return statement is that the return statement is actually more visible, more readable, more maintainable and less error prone. Also, as the return statement will work on any level, you are likely to repeat the control statement an x number of times.

The only reason to want to have the return statement at the end is resource handling - getting rid of the resources you claimed at the start. This is much more common in C/C++ (and even in C++ it is getting less troublesome to do without). In Java, you can rely on the exception mechanism and the finally statement to handle resources as they should be (and in Java 7, the "try with resources" feature).

There are other reasons to choose for the return statement as well. One is the ability to mark variables final: as the compiler knows that return (or a throw for that matter) is the end of the method, you can more easily insert final variables. Final variables - once you get used to them - really make it easy to read code and help you avoid making mistakes.

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

      if (someErrorCondition) {
          return;
      }
  }

This won't work with your approach because the compiler will complain about the final variable not being set (which was the whole idea, not getting into invalid states).

Multitudes of excellent developers and language designers have choosen in favour of multiple return statements. I would urgently advise anyone against going in the other direction.

≈。彩虹 2025-01-03 07:06:44

如果发生异常,您不会返回值。

In case of an exception you don't return a value.

唠甜嗑 2025-01-03 07:06:44

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

Multiple return statements make it easier to follow your code. In this way you immediately see different method return points. As an opposite, one returning 'result' field forces you to find where the field is used after it has been changed. It makes it harder to follow the natural flow of the method. But anyway, usually the desicion is more about style preferences. Make sure you do not mix two approaches.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文