Каков идеальный способ написать «возврат» в методе - PullRequest
4 голосов
/ 16 января 2012

Мне не нравятся методы, имеющие несколько обратных строк.Поэтому я создал возвращаемое значение со строковым результатом - и в каждом условии я пишу результат = что-то ...

Но когда я пишу механизм "try-catch", я должен установить открытый строковый результат .Потому что, если я верну результат в try, компилятор выдаст ошибку и скажет, что не все коды имеют возвращаемое значение.Если я напишу 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?
    }

Ответы [ 5 ]

4 голосов
/ 16 января 2012

Вместо этого вы можете сделать это следующим образом:

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, вероятно, является причинойу вас проблемы с Решарпером.

2 голосов
/ 16 января 2012

Итак, вы утверждаете, что оператор if (или другой оператор потока программы), который помогает вам добраться до этой точки выхода, на самом деле сам по себе не является точкой выхода ?Единственное различие между этим оператором управления и оператором return заключается в том, что оператор return на самом деле является более видимым, более читаемым, более легким в обслуживании и менее подверженным ошибкам.Кроме того, так как оператор return будет работать на любом уровне, вы, вероятно, будете повторять оператор control x раз.

Единственная причина, по которой вы хотите получить оператор return в конце, - обработка ресурсов - получениеизбавиться от ресурсов, которые вы заявили в начале.Это гораздо чаще встречается в C / C ++ (и даже в C ++ без него становится менее хлопотно).В Java вы можете положиться на механизм исключений и оператор finally для обработки ресурсов в том виде, в каком они должны быть (а в Java 7 - возможность "попробовать с ресурсами").

Есть и другие причины для выборадля оператора return.Одним из них является возможность пометить переменные как final: поскольку компилятор знает, что return (или, в этом отношении, бросок) является концом метода, вы можете легче вставить конечные переменные.Конечные переменные - как только вы к ним привыкнете - действительно облегчают чтение кода и помогают избежать ошибок.

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

      if (someErrorCondition) {
          return;
      }
  }

Это не сработает с вашим подходом, потому что компилятор будет жаловаться на конечную переменнуюне задан (что было целой идеей, не попасть в недопустимые состояния).

Множество отличных разработчиков и разработчиков языков выбрали несколько операторов возврата.Я бы срочно советовал никому не идти в другом направлении.

2 голосов
/ 16 января 2012

Некоторые из предложений, включая первую часть принятого ответа и исходный вопрос, имеют большой потенциал для получения неверных результатов, особенно в случае исключения.

Проблема, и мы видели, что это случалось много раз, состоит в том, что когда у вас есть одно возвращаемое значение, незначительные изменения в логике метода неизменно приводят к пути через код, который не ожидался исходным автором метода и приведет к тому, что либо возвращаемая переменная будет неправильно установлена ​​в методе несколько раз, либо не будет установлена ​​вообще.

Определенно бывают случаи, когда вам необходимо собрать значение для возврата вызывающей стороне, а затем выполнить некоторые дополнительные задачи в следующем методе, но в целом это должно быть скорее исключением, чем правилом.

После отслеживания слишком большого количества ошибок, которые были вызваны желанием иметь единственное возвращаемое значение, наши стандарты разработки теперь диктуют, что 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;
    }
}
0 голосов
/ 26 сентября 2013

Несколько операторов возврата облегчают следование вашему коду.Таким образом, вы сразу видите точки возврата различных методов.Напротив, одно возвращаемое поле «результата» вынуждает вас найти, где поле используется после того, как оно было изменено.Это усложняет следование естественному течению метода.Но в любом случае, обычно решение больше зависит от стилевых предпочтений.Убедитесь, что вы не смешиваете два подхода.

0 голосов
/ 16 января 2012

В случае исключения вы не возвращаете значение.

...