2013-08-09 14 views
8

See linia kodu poniżej:Dlaczego ArgumentNullException? Dlaczego nie System.NullReferenceException?

DataTable [] _tables = null; 

// Throws System.NullReferenceException 
_tables.GetType(); 

// Throws System.ArgumentNullException 
_tables.Count(); 

w tej linii kodu mam _tables odniesienia i próbują uzyskać dostęp do swojego systemu definiują funkcje GetType() i Count() zarówno wyjątek throw ale dlaczego .Count() rzuca System.ArgumentNullException, ponieważ mamy taką samą wartość dla odniesienia, który jest null?

+1

możliwe duplikat [ArgumentNullException lub NullReferenceException od metody wydłużania?] (Http://stackoverflow.com/questions/463302/argumentnullexception-or-nullreferenceexception-from-extension-method) –

+0

@ 280Z28 myślę, że w tym que Patrik Hägne prosi o "najlepszy typ wyjątku do rzucenia, gdy metoda rozszerzenia wywołała instancję zerową" ... –

+1

http://blog.mischel.com/2013/05/16/null-parameters-in-extension-methods/ –

Odpowiedz

20

Count() jest extension method na IEnumerable<T>, oświadczył w System.Linq.Enumerable - więc jesteś faktycznie powołanie:

Enumerable.Count(_tables); 

... więc _tablesjest metoda argument, i ma to sens dla wyjątkiem żeby ci to powiedzieć. W rzeczywistości nie usuwasz zmiennej _tables po wywołaniu Count(), natomiast to, gdy zadzwonisz pod numer GetType.

+0

Co masz na myśli mówiąc o "dereferencji zmiennej" _tables' "? –

+2

Oznacza to uzyskanie rzeczywistej wartości referencji - dereferencje (ponieważ referencja jest tylko wskaźnikiem do adresu). – Charleh

+0

Wyczyść każdą koncepcję wzmianki w tej odpowiedzi przez ekspertów ..! 'metoda rozszerzenia 'znalazłem najbardziej interesujące.Dziękuję wszystkim za odpowiedzi. –

4

Count() jest sposób rozszerzenia (a zatem należy wyrzucać ArgumentNullException jeżeli minęło wartości traci swoją null jest nielegalne), a nie sposób na przykład przedmiotu tj Count jest zdefiniowana jako public static int Count<T>(this IEnumerable<T> source).

4

Ponieważ jest to metoda rozszerzenia, a nie metoda instancji.

Ponieważ jest skompilowany do Enumerable.Count(_tables), nie ma zastosowania do NullReferenceException, więc zamiast niego po prostu wyrzuca ArgumentNullException. Jednak GetType jest metodą instancji, więc próbujesz wywołać metodę na null, która ... um, nie działa.

7

Ponieważ Count tutaj jest wezwaniem do przesuwnych metody z _tables jako argumentu - to jest rzeczywiście:

System.Linq.Enumerable.Count(_tables); 

Jeśli nie chcesz użyć metody rozszerzenia: użyj _tables.Length.