Jaka jest najlepsza praktyka przy zwracaniu danych z funkcji. Czy lepiej jest zwrócić wartość Null lub pusty obiekt? I dlaczego jeden powinien robić jeden nad drugim?
Rozważ to:
public UserEntity GetUserById(Guid userId)
{
//Imagine some code here to access database.....
//Check if data was returned and return a null if none found
if (!DataExists)
return null;
//Should I be doing this here instead?
//return new UserEntity();
else
return existingUserEntity;
}
Udawajmy, że w tym programie byłyby prawidłowe przypadki, że w bazie danych o tym identyfikatorze GUID nie byłoby informacji o użytkowniku. Wyobrażam sobie, że w tym przypadku nie byłoby właściwe rzucenie wyjątku? Mam również wrażenie, że obsługa wyjątków może zaszkodzić wydajności.
c#
.net
function
return-value
7wp
źródło
źródło
if (!DataExists)
.Odpowiedzi:
Zwrócenie wartości null jest zwykle najlepszym pomysłem, jeśli zamierzasz wskazać, że żadne dane nie są dostępne.
Pusty obiekt oznacza, że dane zostały zwrócone, a zwrócenie wartości null wyraźnie wskazuje, że nic nie zostało zwrócone.
Ponadto zwrócenie wartości NULL spowoduje wyjątek NULL, jeśli spróbujesz uzyskać dostęp do elementów w obiekcie, co może być przydatne do wyróżnienia błędnego kodu - próba uzyskania dostępu do elementu niczego nie ma sensu. Dostęp do członków pustego obiektu nie zawiedzie, co oznacza, że błędy mogą pozostać nieodkryte.
źródło
bool GetUserById(Guid userId, out UserEntity result)
koniec byłyby - które wolałbym od wartości zerowej „null” i które nie są tak ekstremalne, jak zgłaszanie wyjątku. Pozwala na piękny,null
wolny od kodu kodif(GetUserById(x,u)) { ... }
.To zależy od tego, co ma największy sens dla twojej sprawy.
Czy warto zwracać null, np. „Taki użytkownik nie istnieje”?
Czy ma sens tworzenie domyślnego użytkownika? Jest to najbardziej sensowne, gdy można bezpiecznie założyć, że jeśli użytkownik NIE istnieje, kod wywołujący ma zamiar istnieć, gdy o to poprosi.
Czy ma sens rzucenie wyjątku (a la „FileNotFound”), jeśli kod wywołujący wymaga użytkownika z niepoprawnym identyfikatorem?
Jednak - z punktu widzenia oddzielenia obaw / punktu widzenia SRP, pierwsze dwa są bardziej poprawne. I technicznie pierwszy jest najbardziej poprawny (ale tylko przez włosy) - GetUserById powinien być odpowiedzialny tylko za jedną rzecz - zdobycie użytkownika. Obsługa własnego przypadku „użytkownik nie istnieje” przez zwrócenie czegoś innego może stanowić naruszenie SRP. Rozdzielenie na inną czek -
bool DoesUserExist(id)
byłoby właściwe, jeśli zdecydujesz się rzucić wyjątek.W oparciu o obszerne komentarze poniżej : jeśli jest to pytanie projektowe na poziomie API, ta metoda może być analogiczna do „OpenFile” lub „ReadEntireFile”. „Otwieramy” użytkownika z jakiegoś repozytorium i hydratujemy obiekt z powstałych danych. W tym przypadku odpowiedni może być wyjątek . Może nie być, ale może być.
Wszystkie podejścia są akceptowalne - to po prostu zależy od szerszego kontekstu API / aplikacji.
źródło
Osobiście używam NULL. Wyjaśnia, że nie ma danych do zwrócenia. Ale zdarzają się przypadki, gdy Null Object może być przydatny.
źródło
Jeśli typem zwracanym jest tablica, zwróć pustą tablicę, w przeciwnym razie zwróć null.
źródło
null
. Pozwala na używanie go wforeach
instrukcjach i zapytaniach linq bez obawNullReferenceException
.Powinieneś zgłosić wyjątek (tylko), jeśli konkretna umowa zostanie zerwana.
W twoim konkretnym przykładzie, prosząc o UserEntity na podstawie znanego identyfikatora, byłoby to zależne od tego, czy brak (usuniętych) użytkowników jest oczekiwanym przypadkiem. Jeśli tak, to wróć,
null
ale jeśli nie jest to oczekiwany przypadek, wyrzuć wyjątek.Zauważ, że jeśli funkcja została wywołana
UserEntity GetUserByName(string name)
, prawdopodobnie nie wyrzuciłaby, ale zwróciła null. W obu przypadkach zwrócenie pustej UserEntity byłoby nieprzydatne.W przypadku ciągów, tablic i kolekcji sytuacja jest zwykle inna. Pamiętam pewne wytyczne z MS, że metody powinny akceptować
null
jako „pustą” listę, ale zwracają kolekcje o zerowej długościnull
. To samo dotyczy ciągów znaków. Pamiętaj, że możesz zadeklarować puste tablice:int[] arr = new int[0];
źródło
.Wher(p => p.Lastname == "qwerty")
powinien zwrócić pustą kolekcję, a nienull
.Jest to pytanie biznesowe, zależne od tego, czy istnienie użytkownika o określonym identyfikatorze GUID jest oczekiwanym normalnym przypadkiem użycia tej funkcji, czy też jest to anomalia, która uniemożliwia aplikacji pomyślne wykonanie dowolnej funkcji, którą ta metoda zapewnia użytkownikowi oponować...
Jeśli jest to „wyjątek”, ponieważ brak użytkownika o tym identyfikatorze uniemożliwi aplikacji pomyślne wykonanie dowolnej funkcji (powiedzmy, że tworzymy fakturę dla klienta, do którego wysłaliśmy produkt ... ), wówczas ta sytuacja powinna zgłosić wyjątek ArgumentException (lub inny niestandardowy wyjątek).
Jeśli brakujący użytkownik jest w porządku (jeden z potencjalnych normalnych wyników wywołania tej funkcji), zwróć wartość null ....
EDYCJA: (aby odpowiedzieć na komentarz Adama w innej odpowiedzi)
Jeśli aplikacja zawiera wiele procesów biznesowych, z których co najmniej jeden wymaga pomyślnego ukończenia przez użytkownika, a co najmniej jeden z nich może zakończyć się pomyślnie bez użytkownika, wyjątek powinien zostać zgłoszony dalej w górę stosu wywołań, bliżej miejsca, w którym procesy biznesowe wymagające od użytkownika wywołują ten wątek wykonania. Metody między tą metodą a tym punktem (w którym zgłaszany jest wyjątek) powinny po prostu informować, że nie istnieje żaden użytkownik (null, boolean, cokolwiek - jest to szczegół implementacji).
Ale jeśli wszystkie procesy w aplikacji wymagają użytkownika, nadal rzucałbym wyjątek w tej metodzie ...
źródło
Osobiście zwróciłbym wartość null, ponieważ w ten sposób oczekiwałbym działania warstwy DAL / repozytorium.
Jeśli nie istnieje, nie zwracaj niczego, co można by interpretować jako pomyślne pobranie obiektu,
null
działa tutaj pięknie.Najważniejszą rzeczą jest zachowanie spójności w warstwie DAL / Repos, dzięki czemu nie będziesz się mylić, jak z niej korzystać.
źródło
mam tendencję żeby
return null
jeśli identyfikator obiektu nie istnieje, gdy nie wiadomo wcześniej, czy powinien istnieć.throw
jeśli identyfikator obiektu nie istnieje, kiedy powinien istnieć.Rozróżniam te dwa scenariusze za pomocą tych trzech rodzajów metod. Pierwszy:
Druga:
Trzeci:
źródło
out
nieref
Jeszcze inne podejście polega na przekazaniu obiektu wywołania zwrotnego lub delegata, który będzie działał na wartości. Jeśli wartość nie zostanie znaleziona, wywołanie zwrotne nie zostanie wywołane.
Działa to dobrze, gdy chcesz uniknąć sprawdzania wartości NULL w całym kodzie, a gdy nie można znaleźć wartości, nie jest to błąd. Możesz również zapewnić oddzwonienie, gdy nie zostaną znalezione żadne obiekty, jeśli potrzebujesz specjalnego przetwarzania.
To samo podejście z użyciem pojedynczego obiektu może wyglądać następująco:
Z perspektywy projektowania bardzo podoba mi się to podejście, ale ma tę wadę, że sprawia, że strona wywołująca jest obszerniejsza w językach, które nie obsługują łatwo funkcji pierwszej klasy.
źródło
Używamy CSLA.NET i uważa, że nieudane pobranie danych powinno zwrócić „pusty” obiekt. Jest to w rzeczywistości dość denerwujące, ponieważ wymaga konwencji sprawdzania, czy
obj.IsNew
raczejobj == null
.Jak wspomniano w poprzednim plakacie, zwracane wartości zerowe spowodują natychmiastową awarię kodu, zmniejszając prawdopodobieństwo problemów z ukrywaniem spowodowanych przez puste obiekty.
Osobiście uważam, że
null
jest bardziej elegancki.Jest to bardzo częsty przypadek i jestem zaskoczony, że ludzie tutaj wydają się tym zaskoczeni: w dowolnej aplikacji internetowej dane są często pobierane przy użyciu parametru querystring, który można oczywiście zniekształcić, co wymaga od programisty obsługi przypadków „nie znaleziono” „.
Możesz sobie z tym poradzić:
... ale to dodatkowe połączenie z bazą danych za każdym razem, co może być problemem na stronach o dużym ruchu. Natomiast:
... wymaga tylko jednego połączenia.
źródło
Wolę
null
, ponieważ jest zgodny z operatorem zerowania koalescencji (??
).źródło
Powiedziałbym, że return null zamiast pustego obiektu.
Ale w konkretnej instancji, o której tu wspomniałeś, szukasz użytkownika według identyfikatora użytkownika, który jest swego rodzaju kluczem do tego użytkownika, w takim przypadku prawdopodobnie chciałbym zgłosić wyjątek, jeśli nie znaleziono instancji użytkownika .
Zasadę tę ogólnie przestrzegam:
źródło
Różni się w zależności od kontekstu, ale ogólnie zwracam null, jeśli szukam jednego konkretnego obiektu (jak w twoim przykładzie) i zwracam pustą kolekcję, jeśli szukam zestawu obiektów, ale nie ma żadnego.
Jeśli popełniłeś błąd w kodzie i zwracanie wartości null prowadzi do wyjątków wskaźnika null, wówczas im szybciej to zauważysz, tym lepiej. Jeśli zwrócisz pusty obiekt, jego początkowe użycie może działać, ale później mogą pojawić się błędy.
źródło
Najlepsze w tym przypadku zwracają „null” w przypadku braku takiego użytkownika. Ustaw także metodę statyczną.
Edytować:
Zazwyczaj takie metody są członkami niektórych klas „User” i nie mają dostępu do członków instancji. W takim przypadku metoda powinna być statyczna, w przeciwnym razie musisz utworzyć instancję „Użytkownik”, a następnie wywołać metodę GetUserById, która zwróci inną instancję „Użytkownik”. Zgadzam się, że jest to mylące. Ale jeśli metoda GetUserById należy do klasy „DatabaseFactory” - nie ma problemu z pozostawieniem jej jako elementu instancji.
źródło
Osobiście zwracam domyślną instancję obiektu. Powodem jest to, że oczekuję, że metoda zwróci zero do wielu lub zero do jednego (w zależności od celu metody). Jedynym powodem, dla którego byłby to stan błędu dowolnego rodzaju, przy zastosowaniu tego podejścia, jest to, że metoda nie zwróciła żadnych obiektów i zawsze była oczekiwana (w kategoriach zwrotu jeden do wielu lub pojedynczego).
Jeśli chodzi o założenie, że jest to pytanie z dziedziny biznesu - po prostu nie widzę tego z tej strony równania. Normalizacja typów zwracanych danych jest prawidłowym pytaniem dotyczącym architektury aplikacji. Przynajmniej podlega normalizacji w praktykach kodowania. Wątpię, czy istnieje użytkownik biznesowy, który powie „w scenariuszu X, po prostu daj mu wartość zerową”.
źródło
W naszych obiektach biznesowych mamy 2 główne metody Get:
Aby zachować prostotę w kontekście lub kwestionujesz, będą to:
Pierwsza metoda jest używana podczas uzyskiwania określonych encji, druga metoda jest używana szczególnie podczas dodawania lub edytowania encji na stronach internetowych.
To pozwala nam mieć to, co najlepsze z obu światów w kontekście, w którym są używane.
źródło
Jestem francuskim studentem informatyki, więc wybacz mój słaby angielski. W naszych klasach powiedziano nam, że taka metoda nigdy nie powinna zwracać wartości null ani pustego obiektu. Użytkownik tej metody powinien najpierw sprawdzić, czy szukany obiekt istnieje, zanim spróbuje go zdobyć.
Przy użyciu Javy jesteśmy proszeni o dodanie
assert exists(object) : "You shouldn't try to access an object that doesn't exist";
na początku dowolnej metody, która może zwrócić null, aby wyrazić „warunek wstępny” (nie wiem, co to słowo po angielsku).IMO to naprawdę nie jest łatwe w użyciu, ale tego właśnie używam, czekając na coś lepszego.
źródło
Jeśli sprawa użytkownik nie jest znaleźć pojawia się dość często, a chcesz sobie z tym na różne sposoby, w zależności od okoliczności (czasami rzuca wyjątek, czasami zastępując pusty użytkownika) można też użyć czegoś blisko F # 's
Option
lub Haskell wMaybe
rodzaju , który wyraźnie oddziela przypadek „brak wartości” od „znaleziono coś!”. Kod dostępu do bazy danych może wyglądać następująco:I być używane w ten sposób:
Niestety, wszyscy wydają się rzucać takimi typami.
źródło
Zwykle zwracam zero. Zapewnia szybki i łatwy mechanizm do wykrycia, czy coś się zepsuło bez rzucania wyjątków i używania ton try / catch w całym miejscu.
źródło
W przypadku typów kolekcji zwrócę pustą kolekcję, dla wszystkich innych typów wolę używać wzorców NullObject do zwracania obiektu, który implementuje ten sam interfejs, co interfejs zwracanego typu. Aby uzyskać szczegółowe informacje na temat wzoru, sprawdź tekst linku
Przy użyciu wzorca NullObject byłoby to: -
{// Wyobraź sobie tutaj kod dostępu do bazy danych .....
}
źródło
Ujmując to, co inni powiedzieli w bardziej bezpośredni sposób ...
Wyjątki dotyczą wyjątkowych okoliczności
Jeśli ta metoda jest czystą warstwą dostępu do danych, powiedziałbym, że biorąc pod uwagę jakiś parametr, który zostanie uwzględniony w instrukcji select, można oczekiwać, że nie mogę znaleźć żadnych wierszy, z których można zbudować obiekt, a zatem zwrócenie wartości null byłoby dopuszczalne, ponieważ jest logiką dostępu do danych.
Z drugiej strony, jeśli spodziewałem się, że mój parametr będzie odzwierciedlał klucz podstawowy i powinienem odzyskać tylko jeden wiersz, jeśli otrzymam więcej niż jeden, zwróciłbym wyjątek. 0 jest w porządku, aby zwrócić null, 2 nie jest.
Teraz, gdybym miał jakiś kod logowania, który sprawdził się w stosunku do dostawcy LDAP, a następnie sprawdził w stosunku do DB, aby uzyskać więcej szczegółów, i spodziewałem się, że powinny one być zsynchronizowane przez cały czas, mógłbym wtedy podrzucić wyjątek. Jak powiedzieli inni, to reguły biznesowe.
Teraz powiem, że to ogólna zasada. Są chwile, w których możesz chcieć to przerwać. Jednak moje doświadczenia i eksperymenty z C # (partii) i że Java (trochę), które nauczyło mnie, że jest to znacznie droższe wydajność mądry, aby radzić sobie z wyjątkami niż obsłużyć problemy przewidywalne poprzez logiki warunkowej. Mówię o melodii o 2 lub 3 rzędy wielkości droższe w niektórych przypadkach. Więc jeśli to możliwe, twój kod może skończyć się pętlą, radziłbym zwrócić wartość null i przetestować go.
źródło
Wybacz mój pseudo-php / kod.
Myślę, że to naprawdę zależy od zamierzonego wykorzystania wyniku.
Jeśli zamierzasz edytować / zmodyfikować wartość zwracaną i zapisać ją, zwróć pusty obiekt. W ten sposób możesz użyć tej samej funkcji do zapełnienia danych nowym lub istniejącym obiektem.
Powiedzmy, że mam funkcję, która pobiera klucz podstawowy i tablicę danych, wypełnia wiersz danymi, a następnie zapisuje wynikowy rekord w db. Ponieważ mam zamiar zapełnić obiekt moimi danymi w jakikolwiek sposób, ogromną zaletą może być odzyskanie pustego obiektu z gettera. W ten sposób mogę wykonać identyczne operacje w obu przypadkach. Korzystasz z wyniku funkcji gettera bez względu na wszystko.
Przykład:
Tutaj widzimy, że ta sama seria operacji manipuluje wszystkimi rekordami tego typu.
Jeśli jednak ostatecznym celem wartości zwracanej jest odczytanie i zrobienie czegoś z danymi, zwrócę wartość null. W ten sposób mogę bardzo szybko ustalić, czy dane nie zostały zwrócone i wyświetlić użytkownikowi odpowiedni komunikat.
Zazwyczaj wychwytuję wyjątki w mojej funkcji, która pobiera dane (dzięki czemu mogę rejestrować komunikaty o błędach itp.), A następnie zwracam wartość NULL bezpośrednio od początku. Zasadniczo nie ma znaczenia dla użytkownika końcowego, na czym polega problem, dlatego uważam, że najlepiej jest zawrzeć moje logowanie / przetwarzanie błędów bezpośrednio w funkcji, która pobiera dane. Jeśli utrzymujesz wspólną bazę kodów w dowolnej dużej firmie, jest to szczególnie korzystne, ponieważ możesz wymusić prawidłowe rejestrowanie błędów / obsługę nawet najbardziej leniwego programisty.
Przykład:
To moja ogólna zasada. Do tej pory działało dobrze.
źródło
Interesujące pytanie i myślę, że nie ma „właściwej” odpowiedzi, ponieważ zawsze zależy od odpowiedzialności twojego kodu. Czy Twoja metoda wie, czy żadne znalezione dane nie stanowią problemu? W większości przypadków odpowiedź brzmi „nie” i dlatego zwracanie wartości null i umożliwienie obsłużeniu dzwoniącego sytuacji jest idealne.
Być może dobrym podejściem do odróżnienia metod rzucania od metod zwracających wartość zerową jest znalezienie konwencji w swoim zespole: Metody, które mówią, że coś „dostają”, powinny rzucić wyjątek, jeśli nie ma nic do zdobycia. Metody, które mogą zwracać null, można nazwać inaczej, na przykład „Znajdź ...”.
źródło
Jeśli zwrócony obiekt jest czymś, co można powtórzyć, zwrócę pusty obiekt, aby nie musiałem najpierw testować na wartość NULL.
Przykład:
źródło
Lubię nie zwracać wartości null z żadnej metody, ale zamiast tego używać typu funkcjonalnego Option. Metody, które nie mogą zwrócić wyniku, zwracają pustą opcję zamiast wartości zerowej.
Ponadto metody, które nie mogą zwrócić żadnego wyniku, powinny wskazywać to poprzez ich nazwę. Zwykle umieszczam Try lub TryGet lub TryFind na początku nazwy metody, aby wskazać, że może zwrócić pusty wynik (np. TryFindCustomer, TryLoadFile itp.).
To pozwala dzwoniącemu zastosować różne techniki, takie jak potokowanie zbierania (patrz Rurociąg zbierania Martina Fowlera ) w wyniku.
Oto kolejny przykład, w którym zwracanie Opcji zamiast wartości zerowej jest stosowane w celu zmniejszenia złożoności kodu: Jak zmniejszyć złożoność cykliczną: Typ Funkcjonalny Opcji
źródło
Więcej mięsa do zmielenia: powiedzmy, że mój DAL zwraca NULL dla GetPersonByID, jak niektórzy zalecają. Co powinien zrobić mój (raczej cienki) BLL, jeśli otrzyma NULL? Przekaż NULL i pozwól konsumentowi się tym martwić (w tym przypadku jest to strona ASP.Net)? A może BLL zgłosi wyjątek?
BLL może być używany przez ASP.Net i Win App lub inną bibliotekę klas - myślę, że niesprawiedliwe jest oczekiwanie, że konsument końcowy z natury „dowie się”, że metoda GetPersonByID zwraca wartość null (chyba że użyte są typy null, chyba ).
Uważam (na ile warto), że mój DAL zwraca NULL, jeśli nic nie zostanie znalezione. W PRZYPADKU NIEKTÓRYCH OBIEKTÓW, to jest w porządku - może to być lista 0: wiele rzeczy, więc brak rzeczy jest w porządku (np. Lista ulubionych książek). W takim przypadku moja BLL zwraca pustą listę. W przypadku większości pojedynczych elementów (np. Użytkownik, konto, faktura), jeśli nie mam, to z pewnością jest to problem i rzuca kosztowny wyjątek. Jednak ponieważ pobieranie użytkownika za pomocą unikalnego identyfikatora, który został wcześniej podany przez aplikację, powinno zawsze zwracać użytkownika, wyjątek jest „prawidłowym” wyjątkiem, ponieważ jest wyjątkowy. Końcowy konsument BLL (ASP.Net, f'rinstance) oczekuje tylko, że rzeczy będą hunky-dory, więc zamiast obsługi każdego pojedynczego wywołania GetPersonByID w bloku try-catch zostanie użyty nieobsługiwany moduł obsługi wyjątków.
Jeśli w moim podejściu występuje rażący problem, daj mi znać, ponieważ zawsze chętnie się uczę. Jak powiedzieli inni plakaty, wyjątki są kosztowne, a podejście „najpierw sprawdzanie” jest dobre, ale wyjątki powinny być właśnie takie - wyjątkowe.
Podoba mi się ten post, wiele dobrych sugestii dotyczących scenariuszy „to zależy” :-)
źródło
Sądzę, że funkcje nie powinny zwracać wartości null, dla zdrowia twojej bazy kodu. Mogę wymyślić kilka powodów:
Będzie duża liczba klauzul ochronnych dotyczących zerowego odniesienia
if (f() != null)
.Co to
null
jest zaakceptowana odpowiedź lub problem? Czy wartość null jest poprawnym stanem dla określonego obiektu? (wyobraź sobie, że jesteś klientem kodu). Mam na myśli, że wszystkie typy referencji mogą być zerowe, ale czy powinny?Mając
null
kręci prawie zawsze dać kilka nieoczekiwanych wyjątków NullRef od czasu do czasu jako kod baza rośnie.Istnieje kilka rozwiązań
tester-doer pattern
lub implementacjaoption type
programowania funkcjonalnego.źródło
Jestem zakłopotany liczbą odpowiedzi (w całej sieci), które mówią, że potrzebujesz dwóch metod: metody „IsItThere ()” i metody „GetItForMe ()”, co prowadzi do warunków wyścigu. Co jest złego w funkcji, która zwraca null, przypisując ją do zmiennej i sprawdzając zmienną pod kątem Null wszystko w jednym teście? Mój poprzedni kod C był pełen
if (NULL! = (zmienna = funkcja (argumenty ...))) {
Otrzymujesz więc wartość (lub null) w zmiennej i wynik naraz. Czy ten idiom został zapomniany? Czemu?
źródło
Zgadzam się z większością postów tutaj, które mają tendencję do
null
.Moje rozumowanie jest takie, że generowanie pustego obiektu o właściwościach nie dopuszczających wartości zerowej może powodować błędy. Na przykład jednostka z
int ID
właściwością miałaby wartość początkowąID = 0
, która jest wartością całkowicie prawidłową. Gdyby ten obiekt, w pewnych okolicznościach, został zapisany w bazie danych, byłoby źle.Do wszystkiego z iteratorem zawsze używałbym pustej kolekcji. Coś jak
według mnie to zapach kodu. Właściwości kolekcji nigdy nie powinny mieć wartości zerowej.
Obudowa krawędzi jest
String
. Wiele osób twierdzi, żeString.IsNullOrEmpty
tak naprawdę nie jest to konieczne, ale nie zawsze można odróżnić pusty ciąg znaków od wartości null. Co więcej, niektóre systemy baz danych (Oracle) w ogóle ich nie rozróżniają (''
są przechowywane jakoDBNULL
), więc jesteś zmuszony traktować je jednakowo. Powodem tego jest to, że większość wartości ciągu albo pochodzi z danych wejściowych użytkownika, albo z systemów zewnętrznych, podczas gdy ani pola tekstowe, ani większość formatów wymiany nie ma różnych reprezentacji dla''
inull
. Więc nawet jeśli użytkownik chce usunąć wartość, nie może zrobić nic więcej niż wyczyścić kontrolę wejścia. Rozróżnienienvarchar
pól zerowych i zerowych w bazie danych jest więcej niż wątpliwe, jeśli DBMS nie jest wyrocznią - pole obowiązkowe, które pozwala''
jest dziwne, twój interfejs użytkownika nigdy na to nie pozwala, więc twoje ograniczenia nie są mapowane. Moim zdaniem odpowiedź tutaj polega na tym, aby zawsze traktować je jednakowo.Jeśli chodzi o twoje pytanie dotyczące wyjątków i wydajności: Jeśli zgłaszasz wyjątek, którego nie możesz całkowicie obsłużyć w logice programu, musisz w pewnym momencie przerwać cokolwiek twój program i poprosić użytkownika o ponowne wykonanie tego, co właśnie zrobił. W takim przypadku kara za wydajność a
catch
jest naprawdę najmniejszym z twoich zmartwień - musisz zapytać użytkownika, czy jest słoniem w pokoju (co oznacza ponowne renderowanie całego interfejsu użytkownika lub wysyłanie kodu HTML przez Internet). Jeśli więc nie postępujesz zgodnie ze schematem „ Przebieg programu z wyjątkami ”, nie przejmuj się, po prostu rzuć jeden, jeśli ma to sens. Nawet w skrajnych przypadkach, takich jak „wyjątek walidacji”, wydajność nie jest tak naprawdę problemem, ponieważ w każdym razie musisz ponownie zapytać użytkownika.źródło
Asynchronous TryGet Wzór:
Dla metod synchronicznych, wierzę @Johann Gerell za odpowiedź jest wzór do wykorzystania we wszystkich przypadkach.
Jednak wzorzec TryGet z
out
parametrem nie działa z metodami Async.Dzięki literałom Tuple C # 7 możesz teraz to zrobić:
źródło