W C # powiedz, że chcesz pobrać wartość z PropertyC w tym przykładzie, a ObjectA, PropertyA i PropertyB mogą mieć wartość null.
ObjectA.PropertyA.PropertyB.PropertyC
Jak mogę bezpiecznie uzyskać PropertyC przy najmniejszej ilości kodu?
Teraz sprawdziłbym:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
Byłoby miło zrobić coś więcej takiego (pseudokod).
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
Prawdopodobnie jeszcze bardziej upadł z operatorem koalescencji zerowej.
EDYCJA Pierwotnie powiedziałem, że mój drugi przykład był podobny do js, ale zmieniłem go na psuedo-code, ponieważ zostało prawidłowo wskazane, że nie będzie działać w js.
ObjectA
lubPropertyA
są puste.Odpowiedzi:
W C # 6 możesz użyć operatora warunkowego o wartości Null . Więc oryginalny test będzie wyglądał następująco:
źródło
value
równe, jeśliPropertyC
jest null? lub jeśliPropertyB
jest null? co jeśliObject A
jest zerowe?null
. Zaczyna się od lewej do prawej. Bez cukru syntaktycznego jest to równoznaczne z serią stwierdzeń if, w którychif(propertyX == null) {value = null} else if (propertyY == null){ value = null} else if......
ostateczne ostatnie wyrażenie toif(propertyZ != null) { value = propertyZ }
Metoda krótkiego przedłużenia:
Za pomocą
Ta prosta metoda rozszerzenia i wiele więcej można znaleźć na http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
EDYTOWAĆ:
Po chwilowym użyciu, myślę, że właściwą nazwą tej metody powinno być IfNotNull () zamiast oryginalnego With ().
źródło
Czy możesz dodać metodę do swojej klasy? Jeśli nie, czy myślałeś o użyciu metod rozszerzających? Możesz utworzyć metodę rozszerzenia dla swojego typu obiektu o nazwie
GetPropC()
.Przykład:
Stosowanie:
Przy okazji zakłada się, że używasz platformy .NET 3 lub nowszej.
źródło
Sposób, w jaki to robisz, jest poprawny.
Państwo mogli korzystać trick jak opisany tutaj , używając wyrażeń Linq:
Jednak ręczne sprawdzanie każdej właściwości jest znacznie wolniejsze ...
źródło
Refaktoryzuj, aby przestrzegać prawa Demeter
źródło
Aktualizacja 2014: C # 6 ma nowego operatora o
?.
nazwie „bezpieczna nawigacja” lub „propagacja zerowa”Przeczytaj http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx, aby uzyskać szczegółowe informacje
To od dawna bardzo popularne żądanie https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c-?tracking_code=594c10a522f8e9bc987ee4a5e2c0b38d
źródło
Oczywiście szukasz monady Nullable :
staje się
Zwraca to
null
, jeśli którakolwiek z właściwości dopuszczających wartość null ma wartość null; w przeciwnym razie wartośćValue
.Metody rozszerzenia LINQ:
źródło
SelectMany
metoda rozszerzenia jest używana przezfrom ... in ... from ... in ...
składnię.Zakładając, że masz puste wartości typów, jedno podejście byłoby takie:
Jestem wielkim fanem C #, ale bardzo fajną rzeczą w nowej Javie (1.7?) Jest.? operator:
źródło
Ten kod jest „najmniejszą ilością kodu”, ale nie jest najlepszym rozwiązaniem:
źródło
Kiedy muszę łączyć wywołania w ten sposób, polegam na utworzonej przeze mnie metodzie pomocniczej TryGet ():
W twoim przypadku użyłbyś go tak:
źródło
Widziałem coś w nowym C # 6.0, to jest za pomocą '?' zamiast sprawdzać
na przykład zamiast używać
po prostu używasz
Mam nadzieję, że komuś pomogło.
AKTUALIZACJA:
Możesz to teraz zrobić
źródło
Możesz to zrobić:
A może nawet lepiej:
źródło
możesz użyć następującego rozszerzenia i myślę, że jest naprawdę dobre:
I jest używany w ten sposób:
źródło
Napisałbym własną metodę w typie PropertyA (lub metodę rozszerzenia, jeśli nie jest to twój typ), używając podobnego wzorca do typu Nullable.
źródło
Właśnie natknąłem się na ten post.
Jakiś czas temu w Visual Studio Connect zasugerowałem dodanie nowego
???
operatora.http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4104392-add-as-an-recursive-null-reference-check-opera
Wymagałoby to trochę pracy zespołu ds. Frameworka, ale nie trzeba zmieniać języka, ale po prostu zrobić trochę magii kompilatora. Pomysł był taki, że kompilator powinien zmienić ten kod (składnia nie jest dozwolona w atm)
do tego kodu
Dla sprawdzenia zerowego może to wyglądać
źródło
Napisałem metodę, która akceptuje wartość domyślną, oto jak jej używać:
Oto kod:
źródło
To niemożliwe.
ObjectA.PropertyA.PropertyB
zakończy się niepowodzeniem, jeśliObjectA
ma wartość null z powodu wyłuskiwania odwołań o wartości zerowej, co jest błędem.if(ObjectA != null && ObjectA.PropertyA
... działa z powodu zwarcia, tzn.ObjectA.PropertyA
nigdy nie będzie sprawdzane, czyObjectA
jestnull
.Pierwsza propozycja jest najlepsza i najbardziej przejrzysta z zamiarem. Jeśli cokolwiek, możesz spróbować przeprojektować bez konieczności polegania na tak wielu zerach.
źródło
To podejście jest dość proste, gdy przejdziesz przez lambda gobbly-gook:
Przy użyciu, które może wyglądać następująco:
źródło
W
??
(null koalescencji operatorów) oznacza, że jeśli pierwszy argument jestnull
, należy zwrócić drugi zamian.źródło