Dawno temu dużo programowałem w ADA i normalne było nazywanie argumentów podczas wywoływania funkcji - SomeObject.DoSomething (SomeParameterName => someValue);
Teraz, gdy C # obsługuje nazwane argumenty, myślę o powrocie do tego nawyku w sytuacjach, w których może nie być oczywiste, co oznacza argument.
Możesz argumentować, że zawsze powinno być oczywiste, co oznacza argument, ale jeśli masz argument boolowski, a osoby wywołujące przekazują „prawda” lub „fałsz”, wówczas kwalifikacja wartości za pomocą nazwy sprawia, że strona wywoływania jest bardziej czytelna.
contentFetcher.DownloadNote (uwaga, instrukcja: prawda);
Chyba mógłbym stworzyć Enums zamiast używać true lub false (w tym przypadku ręczne, automatyczne).
Co sądzisz o sporadycznym używaniu nazwanych argumentów, aby ułatwić czytanie kodu?
źródło
Odpowiedzi:
Zostało to zasugerowane w rozwoju C ++, a Stroustrup omawia to w swoim „Design and Evolution of C ++”, na stronach 153 i następnych. Propozycja była dobrze sformułowana i opierała się na wcześniejszych doświadczeniach z Adą. Nie został przyjęty.
Najważniejszym powodem było to, że nikt nie chciał zachęcać do funkcji o dużej liczbie parametrów. Każda dodatkowa funkcja w języku kosztuje coś, a nie było potrzeby dodawania funkcji ułatwiającej pisanie złych programów.
Pojawiły się także pytania o to, jakie były kanoniczne nazwy parametrów, szczególnie w zwykłej konwencji plików nagłówkowych i kodowych. Niektóre organizacje miały dłuższe i bardziej opisowe nazwy parametrów w pliku .h oraz krótsze i łatwiejsze do wpisania nazwy w pliku .cpp (sufiksy plików zastępczych według potrzeb). Wymaganie, aby były takie same, wiązałoby się z dodatkowymi kosztami kompilacji, a pomieszanie nazw między plikami źródłowymi może powodować subtelne błędy.
Można to również obsłużyć, używając obiektów zamiast wywołań funkcji. Zamiast wywołania GetWindow z tuzinem parametrów, utwórz klasę Window z tuzinem prywatnych zmiennych i dodaj settery w razie potrzeby. Łącząc setery, można napisać coś takiego
my_window.SetColor(green).SetBorder(true).SetBorderSize(3);
. Możliwe jest również posiadanie różnych funkcji z różnymi ustawieniami domyślnymi, które wywołują funkcję, która faktycznie działa.Jeśli martwisz się tylko efektem dokumentacji
contentFetcher.DownloadNote(note, manual : true);
, zawsze możesz napisać coś takiegocontentFetcher.DownloadNote(note, /* manual */ true);
, więc nie jest to nawet bardzo pomocne w dokumentacji.źródło
Myślę, że jest to kwestia uczynienia złego kodu bardziej czytelnym, niż „najlepszą praktyką”.
Posiadanie metody (lub wykonawcy), która przyjmuje 20 parametrów, to „nieprzyjemny zapach” i prawdopodobnie jest to spowodowane problemem w twoim projekcie. Jednak jeśli jestem zmuszony do pracy nad kodem, gdy metody wymagają wielu parametrów, wówczas nazwany parametr sprawia, że kod jest trudniejszy do zrozumienia.
Gdy metody mają tylko 1 lub 2 parametry i z nazwy metody jasno wynika, jaki jest parametr, wówczas nazwany parametr nic nie dodaje. To idealny przypadek.
Jeśli cały kod, nad którym pracujesz, jest zapisany jako książka „ czystego kodu ”, to będziesz miał bardzo małe zastosowanie dla nazwanych parametrów, jednak żyjemy w prawdziwym świecie.
źródło
void TrackDataChange(Data oldData, Data newData)
Zgadzam się, że dodanie nazwy parametru czyni ją bardziej czytelną. Jednak większość książek, które przeczytałem, wydaje się uważać przełączniki logiczne za złą praktykę. Czasami to robię:
Zapewnia to większą elastyczność podczas wdrażania interfejsu API. Pozwala także kontrolować przypadek, w którym masz wiele przełączników boolowskich, ale nie wszystkie z nich mogą być aktywne jednocześnie.
źródło
Jestem wielkim zwolennikiem nazwanych parametrów w sytuacjach, w których typy i semantyka nie są jasne w nazwie metody. Z mojego doświadczenia wynika, że niewielu ludzi czyta dokumentację.
Biorąc to pod uwagę, nazwane parametry nie powinny stanowić alternatywy dla tworzenia rozsądnych list argumentów, używania obiektów pomocniczych (do „wiązania” ze sobą semantycznie powiązanych argumentów) i używania wyliczeń, w stosownych przypadkach.
źródło
Myślę, że jest to bardziej przydatne w językach innych niż OO, w których możesz mieć jedną funkcję, która musi coś robić na kilka nieco innych sposobów, a sposób, w jaki określa, co należy zrobić, jest oparty na wartościach parametrów. W świecie OOP po prostu przeciążymy funkcję, ale jeśli nie jest to możliwe, kończysz przekazywanie wiązki flag (lub wiązki wartości, a to, czy są one przekazywane, jest flagą).
Myślę, że jest do pewnego stopnia bardziej czytelna; ale jak wspomnieli inni, posiadanie wielu parametrów jest zapachem kodu, więc nie widzę w tym większego zastosowania w języku obiektowym, takim jak C #.
źródło