Стоит ли бросать исключение из этого метода? - PullRequest
4 голосов
/ 30 августа 2009

Я выполняю некоторую проверку параметров в методе и выдаю исключение, где это необходимо. Нужно ли беспокоиться, вручную выбрасывая исключения этого типа? Пока вызывающая сторона помещена в блок try..catch, создается аналогичное исключение независимо от наличия ручных проверок.

    public static Int16 ToInt16(this byte[] value, int startIndex, bool isBigEndian) {

        // are these exceptions necessary?
        if (value == null) {
            throw new ArgumentNullException("value");
        }

        if ((startIndex + 1) >= value.Length) {
            throw new ArgumentOutOfRangeException("startIndex");
        }    

        return (isBigEndian)
            ? (Int16)((value[startIndex] << 8) | value[startIndex + 1])
            : (Int16)((value[startIndex + 1] << 8) | value[startIndex]);
    }

Это метод расширения, используемый для преобразования 2 байтов в массиве в Int16 с возможностью переключения преобразования Big Endian или Little Endian.

Ответы [ 5 ]

9 голосов
/ 30 августа 2009

Ценность создания исключений здесь заключается в том, что вместо получения исключения с нулевой разыменовью вы получите исключение аргумента, которое наиболее важно сообщает вам недопустимый аргумент. Исключение также более явно указывает на причину, чем общее значение nure deref, которое может быть чем угодно.

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

В настоящее время я не знаю, но в .Net 1.1 и 1.0 Frameworks JIT-компилятор никогда не вставлял бы вызов, в который был брошен вызов. Чтобы избежать этого, часто подразумевается создание другого метода, который будет вызывать само исключение.

Кстати, у вас есть одна ошибка с startIndex + 1> value.Length; это должно быть> = вместо.

5 голосов
/ 30 августа 2009

Согласно Руководству по проектированию библиотеки классов, вы должны проверить все параметры открытых членов ваших типов. http://msdn.microsoft.com/en-us/library/8ey5ey87(VS.71).aspx


ОБНОВЛЕНИЕ: более новая версия: http://msdn.microsoft.com/en-us/library/ms229007.aspx

3 голосов
/ 30 августа 2009

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

Если у вас было два метода, MethodA (int i) и MethodB (int i) , какой из них легче понять?

  • Метод A (1000) бросает ArgumentOutOfRangeException
  • MethodB (1000) бросает IndexOutOfRangeException

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

3 голосов
/ 30 августа 2009

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

Джо

3 голосов
/ 30 августа 2009

Если вы посмотрите на код DotNET Framework (скажем, с помощью Reflector), то обнаружите, что парни из MS выдают эти исключения вручную.

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

...