Подтвердить что ты не робот

ArgumentNullException или NullReferenceException из метода расширения?

Что бы вы считали лучшим типом исключения, который должен быть брошен, когда метод расширения вызывается в экземпляре null (где метод расширения не позволяет его)? Поскольку методы расширения - это не что иное, как статические методы, вы можете утверждать, что это должно быть ArgumentNullException, но, с другой стороны, они используются как методы экземпляров, поэтому было бы более естественным использовать исключение NullReferenceException. Возьмем следующий пример:

public static string ToInvariantString(this IFormattable value, string format)
{
    return value.ToString(format, CultureInfo.InvariantCulture);
}

Таким образом вызывается исключение NullReferenceException, если параметр значения имеет значение null.

Другой пример:

public static string ToInvariantString(this IFormattable value, string format)
{
    if (value == null) throw new ArgumentNullException("value");
    return value.ToString(format, CultureInfo.InvariantCulture);
}

EDIT: В некоторых ответах вы указали, что методы расширения можно вызывать как статический метод, и в этих случаях исключение с нулевой ссылкой было бы неправильным, что является отличным моментом и фактически одной из моих проблем, не уверен, почему я забыл упомянуть об этом в вопросе, в первую очередь.

Кто-то также указал, что неправильно выбрасывать исключение NullReferenceException, и да, это так. Поэтому я не бросаю это, я просто позволяю этому (пусть CLR его бросает), не защищая метод.

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

4b9b3361

Ответ 1

В общем случае исключения включают, вы должны рассматривать метод расширения, как если бы это был обычный статический метод. В этом случае вы должны бросить ArgumentNullException.

Бросить исключение NullReferenceException здесь - плохая идея по нескольким причинам.

  • Нулевая ссылка на самом деле не возникала, так что просмотр одного является неконтуитивным.
  • Бросание исключения NullReferenceException и возникновение исключения NullReferenceException приводят к различным различиям (один из способов увидеть разницу - это код ошибки). Это относится ко многим исключениям, которые бросает CLR.

См. Когда вы можете поймать StackOverflowException (сообщение, которое я сделал по этому вопросу).

  • Допустимо законно вызывать метод расширения так же, как если бы это был обычный метод. В этом случае я бы, конечно, не исключал исключение NullReferenceException, а вместо ArgumentNullException.

Ответ 2

Помимо всех других ответов (которые хороши), я думаю, что стоит посмотреть, что делает Microsoft ради согласованности... и методы расширения в Enumerable все бросают ArgumentNullException, насколько я могу видеть.

Ответ 3

Так как методы расширения могут использоваться в С# 2.0, их можно вызвать так же, как и статические методы (вы не должны использовать их в качестве методов расширения), вы должны использовать ArgumentNullException.

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

Ответ 4

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

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

Ответ 5

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