Czasami natrafiam na metody, w których programista postanowił zwrócić coś, co nie jest krytyczne dla funkcji. Mam na myśli, że patrząc na kod, wygląda na to, że działa tak samo dobrze, void
a po chwili zastanowienia pytam „Dlaczego?” Czy to brzmi znajomo?
Czasami zgadzam się, że najczęściej lepiej jest zwrócić coś takiego bool
lub int
, a nie po prostu zrobić void
. Nie jestem jednak pewien, ogólnie rzecz biorąc, o zaletach i wadach.
W zależności od sytuacji zwracanie int
może uświadomić programowi wywołującemu liczbę wierszy lub obiektów, na które wpływa metoda (np. 5 rekordów zapisanych w MSSQL). Jeśli metoda taka jak „InsertSomething” zwraca wartość logiczną, mogę mieć metodę zaprojektowaną tak, aby zwracała true
sukces, w przeciwnym razie false
. Dzwoniący może zdecydować się na działanie lub nie na podstawie tych informacji.
Z drugiej strony,
- Czy może to prowadzić do mniej wyraźnego celu wywołania metody? Złe kodowanie często zmusza mnie do dwukrotnego sprawdzenia zawartości metody. Jeśli coś zwróci, powie ci, że metoda jest tego typu, że musisz coś zrobić ze zwróconym wynikiem.
- Innym problemem byłoby to, że jeśli implementacja metody jest dla Ciebie nieznana, co deweloper postanowił zwrócić, co nie jest krytyczne pod względem funkcji? Oczywiście możesz to skomentować.
- Wartość zwracana musi zostać przetworzona, gdy przetwarzanie może zostać zakończone w końcowym przedziale metody.
- Co dzieje się pod maską? Czy wywoływana metoda została wywołana z
false
powodu wyrzuconego błędu? A może zwrócił fałsz z powodu wyniku oceny?
Jakie są twoje doświadczenia z tym? Jak byś na to zareagował?
źródło
void
co najmniej informuje programistę, że wartość zwracana przez metodę jest nieistotna; wykonuje akcję, a nie oblicza wartość.Odpowiedzi:
W przypadku wartości zwracanej bool wskazującej powodzenie lub niepowodzenie metody preferuję
Try
paradygmat prefiksu używany w różnych metodach .NET.Na przykład
void InsertRow()
metoda może zgłosić wyjątek, jeśli istnieje już wiersz z tym samym kluczem. Pytanie brzmi: czy uzasadnione jest założenie, że osoba dzwoniąca upewnia się, że jej wiersz jest unikalny przed wywołaniem InsertRow? Jeśli odpowiedź brzmi „nie”, podaję równieżbool TryInsertRow()
wartość „false”, jeśli wiersz już istnieje. W innych przypadkach, takich jak błędy łączności z bazą danych, TryInsertRow nadal może zgłosić wyjątek, zakładając, że utrzymanie łączności z bazą danych jest obowiązkiem osoby dzwoniącej.źródło
IMHO zwracające „kod statusu” wywodzi się z czasów historycznych, zanim wyjątki stały się powszechne w językach od średniego do wyższego poziomu, takich jak C #. W dzisiejszych czasach lepiej jest zgłosić wyjątek, jeśli jakiś nieoczekiwany błąd uniemożliwił pomyślne zakończenie metody. W ten sposób jest pewne, że błąd nie pozostanie niezauważony, a osoba dzwoniąca poradzi sobie z tym odpowiednio. Tak więc w tych przypadkach doskonale jest, aby metoda nie zwracała niczego (tj.
void
) Zamiast logicznej wartości statusu lub kodu statusu liczby całkowitej. (Oczywiście należy udokumentować, jakie wyjątki może zgłosić metoda i kiedy).Z drugiej strony, jeśli jest to funkcja w ścisłym znaczeniu, tzn. Wykonuje pewne obliczenia na podstawie parametrów wejściowych i oczekuje się, że zwróci wynik tego obliczenia, typ zwracany jest oczywisty.
Między nimi jest szara strefa, w której można zdecydować o zwróceniu niektórych „dodatkowych” informacji z metody, jeśli zostanie to uznane za przydatne dla jej rozmówców. Podobnie jak twój przykład dotyczący liczby dotkniętych wierszy we wstawce. Lub w przypadku metody umieszczania elementu w kolekcji asocjacyjnej przydatne może być zwrócenie poprzedniej wartości powiązanej z tym kluczem, jeśli taki istnieje. Takie zastosowania można zidentyfikować, dokładnie analizując (znane i przewidywane) scenariusze użycia interfejsu API.
źródło
Odpowiedź Piotra dobrze obejmuje wyjątki. Inne rozważania dotyczą rozdzielenia poleceń i zapytań
Zasada CQS mówi, że metoda powinna być albo poleceniem, albo zapytaniem, a nie jednym i drugim. Polecenia nigdy nie powinny zwracać wartości, tylko modyfikować stan, a zapytania powinny tylko zwracać, a nie modyfikować stan. Dzięki temu semantyka jest bardzo przejrzysta i pomaga uczynić kod bardziej czytelnym i łatwym w utrzymaniu.
Jest kilka przypadków, w których naruszenie zasady CQS jest dobrym pomysłem. Zazwyczaj dotyczą one wydajności lub bezpieczeństwa wątków.
źródło
Jakąkolwiek ścieżkę zamierzasz iść z tym. Nie ma tam wartości zwracanych do przyszłego użytku (np. Czy funkcje zawsze zwracają wartość true), jest to straszna strata wysiłku i nie sprawia, że kod jest bardziej czytelny. Gdy masz wartość zwracaną, zawsze powinieneś jej używać, a aby móc z niej skorzystać, powinieneś mieć co najmniej 2 możliwe wartości zwracane.
źródło
Pisałem wiele pustych funkcji. Ale odkąd podjąłem całą metodę łączenia pęknięć, zacząłem zwracać to zamiast pustki - równie dobrze mogę pozwolić komuś skorzystać ze zwrotu, ponieważ nie można robić przysiadów z pustką. A jeśli nie chcą nic z tym zrobić, mogą to zignorować.
źródło
Ruby
w którymś momencie wpadłeś? To właśnie wprowadziło mnie do łączenia metod.return Thing.Change1().Change2();
oczekuje zmianyThing
i zwrócenia odniesienia do oryginału, czy też oczekuje zwrócenia odniesienia do nowej rzeczy, która różni się od oryginału, pozostawiając oryginał nietknięty.