Dlaczego metody przyjmujące nieograniczoną liczbę parametrów często definiują przeciążenia przy mniejszej liczbie parametrów?

36

Na przykład System.IO.Path.Combinemetoda w .NET ma następujące przeciążenia:

Combine(params String[])
Combine(String, String)
Combine(String, String, String)
Combine(String, String, String, String)

Jaki jest sens ostatnich trzech?

Pierwszy obejmowałby je wszystkie, ponieważ jeśli przyjrzysz się uważnie, użyje paramssłowa kluczowego. Argument zgodności wstecznej obejmowałby tylko Combine(String, String)wariant, ponieważ była to jedyna wersja do .NET 4.

Alex
źródło

Odpowiedzi:

56

Głównym powodem jest wydajność. Cukier syntaktyczny „nieograniczona liczba argumentów” jest w rzeczywistości szeregiem ciągów. Jeśli przekazujesz tylko jeden ciąg, po co tworzyć tablicę z jednym ciągiem? Zwłaszcza jeśli ~ 90% wywołań tej metody będzie miało 3 lub mniej argumentów, nie ma potrzeby stosowania obiektu tablicy o większej masie. Jest trochę jaśniejszy w pamięci i zajmuje trochę mniej czasu przetwarzania, ponieważ nie potrzebujesz pętli, aby zdefiniować metodę. Jeśli masz trzy ciągi, po prostu kodujesz trzy ciągi.

Greg Burghardt
źródło
Inną rzeczą, na którą należy zwrócić uwagę, jest to, że przekazywanie Combinez zerowym lub jednym segmentem ścieżki nawet nie ma sensu, ale paramswersja na to pozwala.
Matthew
4
Powodem liczby przeciążeń przyjmujących różne liczby argumentów nie jest ich czytelność. Jest to wydajność ze względu na narzut związany z generowaniem tablicy ciągów, a następnie przetwarzaniem ich. Powodem przyjęcia params string[]jest czytelność.
Greg Burghardt
2
Wydajność jest rzeczywiście powodem i uważam, że jest to specjalnie w przypadku, gdy oczekuje się, że funkcja zostanie wywołana z pętli wewnętrznych . Jak adnotacja Brada Abramsa na str. 27 The C # Programming Language, Third Edition mówi: „[C] on C # model tworzy dodatkową alokację obiektów (tablicę zawierającą) niejawnie przy każdym wywołaniu. Rzadko jest to problem, ale wewnętrzny - scenariusze typu pętli, w których może to stać się nieefektywne, sugerujemy zapewnienie przeciążeń dla głównych przypadków i użycie paramsprzeciążenia tylko dla przypadków skrajnych. Przykładem jest StringBuilder.AppendFormat()rodzina przeciążeń. ”
Eliah Kagan
3
@LowFlyingPelican Mono i .NET Framework to nie to samo. Jeśli spojrzysz na wersję .NET Framework , jest to całkiem inne rozwiązanie.
Alex
3
@LowFlyingPelican: Przyczyną frameworku .NET jest wydajność. Powodem wdrożenia tej metody przez Mono była kompatybilność API z .NET. Powodem, dla którego Mono wdrożyło tę metodę w ten sposób, była prostota implementacji (ponieważ mają one znacznie mniej zasobów niż Microsoft).
jhominal
4

Cukier syntaktyczny.

Podczas manipulowania ścieżkami plików niezwykle często występuje niewielka liczba stałych wartości. W takich przypadkach wygodniej jest używać ich bezpośrednio, niż trzeba je pakować do tablicy.

Gort the Robot
źródło
3
Z params już to słodzisz. msdn.microsoft.com/en-us/library/w5zay9db.aspx Nie wymaga tablicy.
Thomas Junk
3
W języku C # masz punkt @Thomas. Jednak .NET obsługuje także inne języki bez params.
Karl Bielefeldt
@ThomasJunk Ten link jest dla mnie niestety martwy, ale jestem pewien, że masz rację, ponieważ mój C # jest mierny. Właśnie widziałem wiele bibliotek z wieloma językami, które robią to tylko po to, aby umożliwić czystszy kod.
Gort the Robot