/ / ArgumentNullException lub NullReferenceException z metody rozszerzenia? - .net, wyjątek, metody rozszerzeń

ArgumentNullException lub NullReferenceException z metody rozszerzenia? - .net, wyjątek, metody rozszerzeń

Co uważasz za najlepszy wyjątek?typ do rzucenia, gdy wywoływana jest metoda rozszerzenia na instancję zerową (gdzie metoda rozszerzenia na to nie pozwala)? Ponieważ metody rozszerzeń są niczym innym, jak metodami statycznymi, można argumentować, że powinien to być ArgumentNullException, ale z drugiej strony są one używane jako metody instancji, więc bardziej naturalne może być użycie wyjątku NullReferenceException. Weźmy następujący przykład:

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

W ten sposób zostanie wygenerowany wyjątek NullReferenceException, jeśli parametr value ma wartość null.

Innym przykładem będzie:

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

EDYTOWAĆ: W niektórych z odpowiedzi wskazałeś tometody rozszerzenia mogą być nazywane jak metoda statyczna i w tych przypadkach zerowy wyjątek odwołania byłby błędny, co jest świetnym punktem, a właściwie jednym z moich problemów, nie jestem pewien, dlaczego zapomniałem wspomnieć o tym w pytaniu w pierwszej kolejności .

Ktoś wskazał również, że jest to niewłaściwe, aby rzucić wyjątek NullReferenceException, i tak, to jest. Dlatego nie wyrzucam go, po prostu pozwalam, aby to się stało (niech CLR go wyrzuci), nie chroniąc metody.

Myślę, że jestem zwolennikiem ArgumentNullException (thatsczego do tej pory używam), ale nadal uważam, że jest przynajmniej miejsce na argumentowanie przeciwko NullReferenceException, ponieważ wydaje się bardziej naturalne w większości miejsc, w których metoda będzie używana.

Odpowiedzi:

34 dla odpowiedzi nr 1

Ogólnie rzecz biorąc, uwzględnione wyjątki powinny traktować metodę rozszerzenia tak, jakby była normalną metodą statyczną. W takim przypadku należy rzucić wyjątek ArgumentNullException.

Zgłaszanie tutaj wyjątku NullReferenceException jest złym pomysłem z kilku powodów

  • Odwołanie zerowe w rzeczywistości nie wystąpiło, więc widzenie jednego jest sprzeczne z intuicją
  • Zgłaszanie wyjątku NullReferenceException i powodowanieWystąpienie wyjątku NullReferenceException daje wyraźnie różne wyjątki (Jednym ze sposobów odróżnienia jest kod błędu). Dotyczy to wielu wyjątków, które są zgłaszane przez CLR.

Widzieć Kiedy można złapać wyjątek StackOverflowException (post, który zrobiłem na ten temat).

  • Jest to całkowicie zgodne z prawem, aby wywoływać metodę rozszerzenia tak, jakby była zwykłą metodą.W takim przypadku na pewno nie z wyjątkiem wyjątku NullReferenceException, ale zamiast tego ArgumentNullException.

21 dla odpowiedzi nr 2

Oprócz wszystkich innych odpowiedzi (które są dobre)Myślę, że warto spojrzeć na to, co Microsoft robi ze względu na spójność ... a metody rozszerzeń w Enumerable wszystkie rzucają ArgumentNullException na tyle, na ile widzę.


6 dla odpowiedzi nr 3

Ponieważ metody rozszerzeń mogą być używane w języku C # 2.0 i można je nazwać podobnie jak metody statyczne (nie musisz ich używać jako metod rozszerzania), powinieneś użyć ArgumentNullException.

Tylko dlatego, że oni Popatrz podobne metody na typie nie oznaczają, że są lub są zawsze nazywane jak jeden.


1 dla odpowiedzi nr 4

Z punktu widzenia użytkownika metoda wygląda i działa jak metoda instancji, więc gdybym był nimi, oczekiwałbym ujrzenia wyjątku NullReferenceException.

To powiedziawszy, sugerowałbym rzucenie jednego lub drugiego wyraźnie w kod, zamiast po prostu "dzieje się", aby rzucić tak jak w pierwszym przykładzie.


1 dla odpowiedzi nr 5

ArgumentNullException. Jest Nie wymaganie wywoływania metod rozszerzeń tak, jakby były metodami instancji. Możesz nazwać je tak, jakby były normalnymi metodami. Wyjątek NullReferenceException byłby w tym przypadku całkowicie niepoprawny.