Должен ли метод, который может генерировать исключение, иметь «throw» в своем имени?

#c#

#c#

Вопрос:

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

 public void Compute() {
    this.CheckIfCallerAuthorizedOrThrow(); // Is it a good name? Better idea?

    // ...
}
  

Я хочу убедиться, что кто-то, кто читает код, понимает, что поток метода может быть нарушен здесь исключением. Это хорошая или плохая практика в данном случае иметь имя метода с «throw» в нем?

Комментарии:

1. FWIW, для такого метода (единственная цель — генерировать исключение, если что-то не удается) Я обычно использую Require — например RequireAuthorizedCaller() . Мне нравится действие спереди, и, хотя там не сказано «throw», я думаю, что оно выделяется довольно хорошо. Большой ключ должен быть согласованным. (Более очевидной альтернативой может быть FailUnlessCallerAuthorized или ThrowUnlessCallerAuthorized .. ключ в согласованности.)

Ответ №1:

Честно говоря, имя метода должно точно описывать, что он должен делать. Так что, в некотором смысле, это хорошее название. Однако исключение — это способ сказать «Этот метод не смог успешно завершиться, и вот почему …». Практически каждый написанный вами метод может генерировать исключение, поэтому не имеет смысла документировать исключения в имени каждого метода.

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

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

 private void doSomethingOrThrow(object args)
{
    if (args == null)
        throw new ArgumentNullException();
    doSomething();
}
  

Итак, вкратце, это потенциально подходящее название метода. Я просто не стал бы использовать «throw» в каждом отдельном методе, который генерирует исключения. Кроме того, хорошему разработчику в любом случае нужно будет заглянуть в документацию, чтобы увидеть, какие исключения генерируются (я, конечно, надеюсь, что он не просто постоянно ловит общее исключение …)

Ответ №2:

Нет, это начинает выглядеть так, как проверенные исключения Java. Скорее документируйте все генерируемые исключения, используя XML-документацию. Например:

 /// <summary>
/// Checks to see if the caller is authorized to access the resource.
/// </summary>
/// <exception cref="ArgumentException">
/// Throws invalid argument exception when an invalid parameter is supplied.
/// </exception>
CheckIfCallerAuthorized(sring myArgument)
{
  throw new ArgumentException("Invalid argument was provided for myArgument.");
}
  

Комментарии:

1. Конечно, но теперь невозможно знать, что поток кода может быть нарушен этим методом

2. Это точно такой же стиль, который вы найдете в самой .NET Framework, поэтому рекомендуется следовать тем же рекомендациям и документировать свои исключения. Пользователь функции должен просмотреть документы, чтобы увидеть, было ли выдано какое-либо исключение.

3. Я бы ожидал, что CheckIfCallerAuthorized возвращает значение, указывающее, авторизован ли вызывающий. Назовите его Assert... или Ensure...

Ответ №3:

Любой метод может генерировать исключения, поэтому добавление OrThrow / Throws необязательно обеспечивает достаточное значение, чтобы сделать name длиннее.

Попробуйте использовать assert / обеспечить / verify вместо «проверить» (что, по-видимому, должно быть true / false) в имени. Т.е. посмотрите, кажется ли вам разумным, что следующая строка после «EnsureCallerAuthorized» будет выполняться только авторизованным пользователем.

Ответ №4:

Очевидно, что это вопрос личного вкуса, но более распространенная идиома относится к семейству «assert», что-то вроде assertCallerIsAuthorized() .

Ответ №5:

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

Комментарии:

1. что-то может быть достаточно ограничивающим показ, чтобы потребовать завершения метода, но при этом быть предсказуемым заранее — например, я пишу сериализатор: если кто-то предоставит мне поток только для чтения для записи, это определенно заслуживает броска. Использование методов проверки работоспособности, которые генерируют throw, совершенно разумно и не совсем совпадает с управлением потоком