Вы бросаете исключение, когда знаете, что вызываемый вами метод просто выбрасывает ту же самую вещь? - PullRequest
1 голос
/ 04 ноября 2010

Скажем, у меня есть такой метод *:

public T GetItem(int index)
{
    if (index < 0 || index >= _privateList.Count)
    {
        throw new ArgumentOutOfRangeException("index");
    }

    return _privateList[index];
}

Вы бы включили это throw или не указали? С одной стороны, я чувствую, что хорошо обрабатывать некорректный ввод сразу, поскольку это позволяет вам чувствовать себя более уверенно с тем, с чем вы имеете дело, при написании реального кода реализации. Но в этом случае, если проверка границ была опущена, конечный результат будет почти таким же (список 1006 * выдаст ArgumentOutOfRangeException вместо включающего типа).

Кроме того, поскольку приведенный выше код проверяет что-то, что я, разработчик, знаю, будет проверяться в любом случае (при вызове _privateList[index]), кажется, я заставляю код делать больше работы, чем нужно выше, фактически выполняя один и тот же набор сравнений дважды.

Буду признателен за любые указания по этому вопросу.

* В частности, я говорю о .NET (C #), но я бы предположил, что один и тот же или аналогичный вопрос может быть задан для многих различных языков / структур - отсюда и тег «независимый от языка».

Ответы [ 4 ]

5 голосов
/ 04 ноября 2010

Я стараюсь не добавлять шум (код без значения). Если бы мое исключение было бы более полезным для меня, я бы выбросил свое исключение, но если оно все равно, ясность кода имеет приоритет.

3 голосов
/ 04 ноября 2010

В .net 4 я бы определил код контракта для этого условия.В более ранних версиях .net я обычно не беспокоился о том, чтобы вручную выдавать такое исключение.

И IMO существует большая разница между кодом библиотеки и кодом приложения.В коде библиотеки я более осторожен с четко определенным поведением ошибок и выбрасываю точно правильное исключение, чем в коде приложения.

2 голосов
/ 04 ноября 2010

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

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

Еще одним соображением является то, что происходит при развертывании сборки Release вашего кода. Без оператора throw вполне вероятно, что этот конкретный код будет встроенным. Другими словами, вы не увидите метод GetItem () в верхней части стека. Это может затруднить поиск истинного источника исключения, особенно из-за того, что у трассировок стека выпуска нет номеров строк.

Тогда стоимость актуальна. В этом случае он достаточно низкий, может быть наносекунда или две, если свойство Count достаточно дешево. Но фактическая работа, проделанная этим методом, также очень дешева. Ваш тест делает его на 20% медленнее. Это метод, который вполне может жить глубоко на критическом пути программы. Чем больше метод делает, тем менее актуальным становится дополнительный тест.

1 голос
/ 04 ноября 2010

Я бы никогда не выдал того же исключения, которое было бы вызвано вызываемым методом.

Но я бы (и сделал!) Выбрасывать исключения, которые предоставляют больше информации - дают некоторый контекст для ошибки.

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

Чтобы немного изменить ваш пример:

public OrderLine GetOrderLineint index)
{
    if (index < 0 || index >= _privateList.Count)
    {
        throw new ArgumentOutOfRangeException(
            "index",
            "No OrderLine available at index " + index.ToString());
    }

    return _privateList[index];
}

Таким образом, вы все равно получаете достаточно отладочной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...