Czy metoda jest wywoływana z wartością zerową, czy też daje wyjątek odwołania zerowego?
MyObject myObject = null;
myObject.MyExtensionMethod(); // <-- is this a null reference exception?
Jeśli tak jest, nigdy nie będę musiał sprawdzać parametru „this” pod kątem wartości null?
c#
parameters
null
extension-methods
tpower
źródło
źródło
Cannot perform runtime binding on a null reference
.Odpowiedzi:
To zadziała dobrze (bez wyjątku). Metody rozszerzeń nie używają wywołań wirtualnych (tzn. Używa instrukcji iloczynu „call”, a nie „callvirt”), więc nie ma sprawdzania wartości zerowej, chyba że sam napiszesz ją w metodzie rozszerzenia. Jest to przydatne w kilku przypadkach:
itp
Zasadniczo połączenia do połączeń statycznych są bardzo dosłowne - tj
staje się:
gdzie oczywiście nie ma kontroli zerowej.
źródło
Dodatek do poprawnej odpowiedzi od Marc Gravell.
Możesz otrzymać ostrzeżenie z kompilatora, jeśli jest oczywiste, że ten argument jest pusty:
Działa dobrze w czasie wykonywania, ale generuje ostrzeżenie
"Expression will always cause a System.NullReferenceException, because the default value of string is null"
.źródło
Jak już odkryłeś, ponieważ metody rozszerzenia są po prostu gloryfikowanymi metodami statycznymi, będą one wywoływane z
null
przekazanymi referencjami, bezNullReferenceException
rzucania. Ale ponieważ dla wywołującego wyglądają one jak instancyjne metody, powinny również tak się zachowywać . Następnie przez większość czasu należy sprawdzićthis
parametr i zgłosić wyjątek, jeśli jestnull
. Nie można tego robić, jeśli metoda wyraźnie dba onull
wartości, a jej nazwa wskazuje ją należycie, jak w poniższych przykładach:Jakiś czas temu napisałem też o tym blogu .
źródło
Wartość pusta zostanie przekazana do metody rozszerzenia.
Jeśli metoda spróbuje uzyskać dostęp do obiektu bez sprawdzania, czy ma wartość NULL, wówczas tak, zgłosi wyjątek.
Facet napisał tutaj metody rozszerzeń „IsNull” i „IsNotNull”, które sprawdzają, czy odwołanie zostało przekazane null, czy nie. Osobiście uważam, że jest to aberracja i nie powinna była ujrzeć światła dziennego, ale jest to całkowicie poprawna wersja c #.
źródło
Jak zauważyli inni, wywołanie metody rozszerzenia w odwołaniu null powoduje, że argument ten ma wartość null i nic innego się nie wydarzy. To rodzi pomysł na użycie metod rozszerzenia do napisania klauzul ochronnych.
Możesz przeczytać ten artykuł, aby uzyskać przykłady: Jak zmniejszyć złożoność cyklomatyczną: klauzula ochronna Krótka wersja to:
Jest to metoda rozszerzenia klasy łańcuchowej, którą można wywołać w odwołaniu zerowym:
Wywołanie działa dobrze tylko dlatego, że środowisko wykonawcze z powodzeniem wywoła metodę rozszerzenia przy zerowym odwołaniu. Następnie możesz użyć tej metody rozszerzenia do implementacji klauzul ochronnych bez niechlujnej składni:
źródło
Metoda rozszerzenia jest statyczna, więc jeśli nie podoba ci się ten obiekt MyObject, nie powinno to stanowić problemu, szybki test powinien to zweryfikować :)
źródło
Jest kilka złotych zasad, kiedy chcesz, aby były czytelne i pionowe.
W twoim przypadku - DesignByContract jest zepsuty ... będziesz wykonywać logikę na instancji zerowej.
źródło