Czy jest jakiś powód, aby używać tablicy, gdy listy są dostępne? [Zamknięte]

30

Wygląda na to, że List<T>w języku C # można zrobić wszystko, co tablica, i więcej, i wydaje się równie wydajna pod względem pamięci i wydajności, jak tablica.

Dlaczego więc miałbym kiedykolwiek chcieć używać tablicy?

Oczywiście nie pytam o przypadki, w których API lub inne zewnętrzne ograniczenie (tj. Funkcja Main) wymaga ode mnie użycia tablicy ... Pytam tylko o tworzenie nowych struktur danych we własnym kodzie.

JoelFan
źródło
56
Do wdrożeniaList<T>
maniak zapadkowy,
43
is also just as efficient in memory and performance as an array- um. Skąd masz takie pojęcie?
Oded
12
Wiele wymiarów jak var test = new string[5,5];)
Knerd
7
Istnieje również powszechnie używana tablica bajtów [].
SBoss,
11
Dla C # konkretnie Eric Lippert pisał o tym w blogs.msdn.com/b/ericlippert/archive/2008/09/22/... .
Mephy

Odpowiedzi:

26

Z tego samego powodu, gdy nie jeżdżę ciężarówką, kiedy jadę do pracy. Nie używam czegoś, czego nie będę używać funkcji.

Przede wszystkim tablica jest prymitywną konstrukcją, więc tablica jest na pewno szybsza i wydajniejsza niż List <>, więc twój argument nie jest prawdziwy. Tablica jest również dostępna wszędzie i znana przez programistów używających różnych języków i platform.

Najważniejszym powodem, dla którego używam tablicy zamiast List <> jest sugerowanie, że dane mają stałą długość . Jeśli nie dodam ani nie usunę żadnych elementów z tego zbioru danych, chcę się upewnić, że typ to odzwierciedla.

Kolejną rzeczą jest założenie, że wdrażasz nową strukturę danych i przeczytałeś o niej kilka artykułów. Teraz, wdrażając określone algorytmy, nie zawsze możesz polegać na czyimś zastosowaniu typu ogólnego przeznaczenia. Zmienia się z .NET na Mono, a nawet pomiędzy różnymi wersjami frameworka.

Czasami łatwiej jest przenieść część kodu, który używa tablicy zamiast typu zależnego od frameworka.

Mert Akcakaya
źródło
4
W jaki sposób tablica jest „szybsza” niż lista, biorąc pod uwagę, że List<T>jest implementowana przy użyciu tablicy? Jeśli znasz wcześniej liczbę elementów (co musisz wiedzieć podczas korzystania z tablicy), możesz skorzystać z tej wiedzy podczas inicjowania listy.
Theodoros Chatzigiannakis,
1
@TheodorosChatzigiannakis Korzystając z tablicy, przydzielamy pamięć i po prostu wykonujemy przypisania, zwykłe malloc (), bez narzutu. Podczas korzystania z Listy <> „dodajesz” elementy, a podczas dodawania elementów Lista <> dokonuje pewnej kontroli granic i wywołuje metodę sureCapacity, która skopiuje zawartość do innej nowo przydzielonej tablicy, jeśli bieżąca pojemność nie jest wystarczająca. Oznacza to, że jeśli nie trzeba dynamicznie alokować nowej pamięci, wydajność List nie jest tak dobra jak tablica.
Mert Akcakaya,
4
Co mówisz, jest słuszne, ale zakłada, że albo nie znamy liczbę elementów wcześniej (w którym to przypadku, tablice nie są użyteczne w każdym razie) albo że my zrobić znać liczbę elementów wcześniej, ale celowo nie używaj w przypadku listy. Jeśli będziemy robić użyć liczby elementów, aby zainicjować listę żądanej pojemności, mamy tylko jeden przydział array (do momentu osiągnięcia tej pojemności), co płacimy te same koszty wykonania. Wszystkie pozostałe typowe operacje są równe (wyszukiwanie, wyszukiwanie według indeksu, przypisywanie według indeksu), z wyjątkiem kolejnych dodań (których tablic w ogóle nie ma).
Theodoros Chatzigiannakis,
3
@TheodorosChatzigiannakis: Tablice szybsze niż listy. Wystarczy uruchomić prosty test porównawczy, aby to sprawdzić.
Mehrdad,
1
@TheodorosChatzigiannakis, tak, ale nadal istnieją kontrole graniczne.
Mert Akcakaya,
18

Potrzebujesz tablic, aby zarządzać kolekcją zmiennych struktur i oczywiście, co moglibyśmy zrobić bez nich.

struct EvilMutableStruct { public double X; } // don't do this

EvilMutableStruct[] myArray = new EvilMutableStruct[1];
myArray[0] = new EvilMutableStruct()
myArray[0].X = 1; // works, this modifies the original struct

List<EvilMutableStruct> myList = new List<EvilMutableStruct>();
myList.Add(new EvilMutableStruct());
myList[0].X = 1; // does not work, the List will return a *copy* of the struct

(zwróć uwagę, że mogą istnieć przypadki, w których pożądana jest tablica modyfikowalnych struktur, ale zwykle to różne zachowanie modyfikowalnych struktur w obrębie tablic w porównaniu do innych kolekcji jest źródłem błędów, których należy unikać)


Mówiąc poważniej, potrzebujesz tablicy, jeśli chcesz przekazać element przez referencję . to znaczy

Interlocked.Increment(ref myArray[i]);  // works
Interlocked.Increment(ref myList[i]);   // does not work, you can't pass a property by reference

Może to być przydatne w przypadku kodu zabezpieczającego wątki bez blokady.


Potrzebujesz tablicy, jeśli chcesz szybko i skutecznie zainicjować kolekcję o stałym rozmiarze z wartością domyślną .

double[] myArray = new double[1000]; // contains 1000 '0' values
                                     // without further initialisation

List<double> myList = new List<double>(1000) // internally contains 1000 '0' values, 
                                             // since List uses an array as backing storage, 
                                             // but you cannot access those
for (int i =0; i<1000; i++) myList.Add(0);   // slow and inelegant

(zauważ, że byłoby możliwe zaimplementowanie konstruktora dla List, który robi to samo, po prostu c # nie oferuje tej funkcji)


potrzebujesz tablicy, jeśli chcesz efektywnie kopiować części kolekcji

Array.Copy(array1, index1, array2, index2, length) // can't get any faster than this

double[,] array2d = new double[10,100];
double[] arraySerialized = new double[10*100];
Array.Copy(array2d, 0, arraySerialized, 0, arraySerialized.Length);
// even works for different dimensions

(znowu, jest to coś, co można zaimplementować również dla List, ale ta funkcja nie istnieje w C #)

HugoRune
źródło
Jeśli typ ma reprezentować grupę powiązanych, ale niezależnych zmiennych sklejonych razem z taśmą klejącą (np. Współrzędne punktu), struktura pola odsłoniętego jest najlepszą reprezentacją. Jeśli zmienna ma zawierać kilka takich grup, najlepszą reprezentacją jest tablica tego typu struktury. Nie należy używać zmiennych struktur w miejscach, w których chce się obiektu, ale to nie znaczy, że należy używać obiektów lub rzeczy, które udają obiekty w miejscach, w których chce się wiązki zmiennych sklejonych razem z taśmą klejącą.
supercat
Istnieją sytuacje, w których możesz chcieć mieć zmienną strukturę, na przykład gdy potrzebujesz ostatniego kawałka wydajności i nie stać Cię na przydział sterty i referencje, i wtedy najlepszym wyborem jest tablica struktur. Dobry esej tutaj . Nie zgadzam się jednak, że klasa nie powinna reprezentować „wiązki zmiennych sklejonych razem”. Koncepcyjne struktury i klasy są w większości takie same, różnice są przede wszystkim ze względu na szczegóły implementacji.
HugoRune,
Jeśli ktoś chce użyć zbioru odniesień do obiektów zmiennych jako zbioru niezależnych grup zmiennych niezależnych, musi ustanowić i utrzymywać niezmiennik, że każdy element identyfikuje obiekt, do którego nie istnieją inne nie efemeryczne odniesienia w dowolnym miejscu we wszechświecie. Z pewnością można to zrobić (i często tak jest), ale w języku lub ramach nie ma nic, co pomogłoby programiście w utrzymaniu tego niezmiennika. Z kolei tablica o długości 100 typu struktury z czterema polami instancji automatycznie i trwale obuduje 400 zmiennych niezależnych.
supercat
Myślę, że te komentarze są niewłaściwym miejscem do dalszego omawiania tego problemu, a ponieważ dodałeś własną odpowiedź , nie ma potrzeby kopiowania tutaj tych informacji. Wystarczy powiedzieć, że tablice mogą być używane do zarządzania zmiennymi strukturami. To, czy i kiedy użyć zachowania implementacji tych struktur w celu wymuszenia pewnych ograniczeń danych, naprawdę wykracza poza zakres mojej odpowiedzi.
HugoRune,
15

Dlaczego więc miałbym kiedykolwiek chcieć używać tablicy?

Rzadko będziesz miał scenariusz, w którym wiesz , że potrzebujesz stałej liczby elementów. Z punktu widzenia projektowania należy tego unikać. Jeśli potrzebujesz 3 rzeczy, natura biznesu oznacza, że ​​bardzo często będziesz potrzebować 4 rzeczy w następnej wersji.

Mimo to, gdy tak naprawdę występuje ten rzadki scenariusz, przydatne jest użycie tablicy do wymuszenia niezmiennika o ustalonym rozmiarze. Daje to sygnał innym programistom, że ma ustalony rozmiar i pomaga zapobiegać niewłaściwemu użyciu, gdy ktoś dodaje lub usuwa element - przełamując oczekiwania w innym miejscu w kodzie.

Telastyn
źródło
23
Rozmiar tablic nie jest ustalony w momencie pisania kodu. Może i często jest zmienną czasu wykonywania. Po prostu nigdy się nie zmienia po utworzeniu tablicy .
11
Nie jest niczym niezwykłym radzenie sobie ze stałą liczbą elementów. Jeśli pracujesz z punktami 3D, prawdopodobnie nie będziesz pracować z punktami 5D w żadnym momencie w przyszłości. Większe problemy z tablicami polegają na tym, że są one zmienne i nie mają wygodnych etykiet dołączonych do ich elementów.
Doval,
3
@JanDvorak Listy mogą się kurczyć lub rosnąć, a zatem nie mają sensu w żadnym kontekście obejmującym określoną liczbę elementów.
Doval,
9
Rzadko? Nie wszyscy pracują na super skomplikowanych ultra-konfigurowalnych potworach dla przedsiębiorstw.
whatsisname
3
Bardzo często stosuje się stałą liczbę elementów. Upewnij się tylko, że długość jest zdefiniowana przez stałą, więc kiedy w następnej wersji zwiększysz liczbę elementów z 3 do 4, po prostu zmienisz stałą i wszystko, co na tym polega, zostanie dostosowane.
Hans
9

Na twoje pytanie już wcześniej udzielono odpowiedzi .

i wydaje się równie efektywny pod względem pamięci i wydajności jak tablica.

To nie jest Z pytania, które podłączyłem:

List/foreach:  3054ms (589725196)
Array/foreach: 1860ms (589725196)

Tablice są dwa razy szybsze w niektórych ważnych przypadkach. Jestem pewien, że użycie pamięci również różni się nietradycznie.

Ponieważ główna przesłanka twojego pytania została w ten sposób pokonana, zakładam, że to odpowiada na twoje pytanie. Ponadto czasami tablice są wymuszane na Tobie przez API Win32, moduł cieniujący twojego GPU lub inną bibliotekę inną niż DotNet.

Nawet w DotNet niektóre metody zużywają i / lub zwracają tablice (takie jak String.Split). Co oznacza, że albo trzeba teraz jeść koszt dzwoni ToListi ToArrayprzez cały czas, czy trzeba odpowiadać i użycie tablicy, ewentualnie kontynuując cykl propagując tym biednym dalszych użytkowników swoim kodzie.

Więcej pytań i odpowiedzi na temat przepełnienia stosu na ten temat:

Superbest
źródło
Co ciekawe, że punkty odpowiedź, że jeśli używasz staromodne indeksowanych pętle ( dla zamiast foreach ) różnica wydajności jest minimalny.
user949300,
3

Oprócz powodów wymienionych w innych odpowiedziach literał tablicowy deklaruje mniej znaków:

var array = new [] { "A", "B", "C" };
var list = new List<string>() { "A", "B", "C" };

Użycie tablicy zamiast Listpowoduje, że kod jest nieco krótszy i nieco bardziej czytelny w przypadkach, gdy (1) musisz podać IEnumerable<T>literał lub (2), gdzie inna funkcjonalność Listnie ma znaczenia i musisz użyć listy podobnej do listy dosłowny.

Robiłem to od czasu do czasu w testach jednostkowych.

ikh
źródło
1
Tak, aby dodać. Działa również, gdy musisz zdać IList <T>
Esben Skov Pedersen
+1, często mam operację na kilku obiektach tego samego typu, które nie znajdują się w kolekcji. To proste, krótkie i jasne, napisać foreach( var x in new []{ a, b, c ) ) DoStuff( x )lub new []{ a, b, c ).Select( ... )etc
stijn
3

Jest to ściśle z perspektywy OO.

Chociaż nie mogę wymyślić powodu, aby przekazać tylko tablicę, z pewnością widzę sytuacje, w których reprezentacja tablicy wewnątrz klasy jest prawdopodobnie najlepszym wyborem.

Chociaż istnieją inne opcje, które dają podobne cechy, żadna nie wydaje się tak intuicyjna jak tablica dla problemów związanych z przetwarzaniem permutacji, zagnieżdżona dla pętli, reprezentacji macierzy, map bitowych i algorytmów przeplatania danych.

Istnieje znaczna liczba dziedzin naukowych, które w dużym stopniu opierają się na matematyce matematycznej. (np. przetwarzanie obrazu, korekcja błędów danych, cyfrowe przetwarzanie sygnału, ryza zastosowanych problemów matematycznych). Większość algorytmów w tych polach jest napisana w kategoriach wykorzystania wielowymiarowych tablic / macierzy. Bardziej naturalne byłoby więc zaimplementowanie algorytmów, które są zdefiniowane, niż uczynienie ich bardziej „programowymi” przyjaznymi kosztem utraty bezpośrednich powiązań z dokumentami, na których oparte są algorytmy.

Tak jak powiedziałem, w tych przypadkach prawdopodobnie można uniknąć korzystania z list, ale to dodaje kolejną warstwę złożoności oprócz już złożonych algorytmów.

Maczać
źródło
3

Dotyczy to również innych języków, które również mają listy (takich jak Java lub Visual Basic). Są przypadki, w których trzeba użyć tablicy, ponieważ metoda zwraca tablicę zamiast listy.

W prawdziwym programie nie sądzę, aby tablica była używana bardzo często, ale czasami wiesz, że dane będą miały stały rozmiar i podoba ci się niewielki wzrost wydajności uzyskiwany z używania tablicy. Mikrooptymalizacja byłaby słusznym powodem, podobnie jak metoda zwracająca listę lub potrzeba wielowymiarowej struktury danych.

Dylan Meeus
źródło
1
Wiele języków nie ma nawet osobnych kolekcji list i tablic. Z drugiej strony używanie list<T>gdzie vector<T>będzie działać jest katastrofalnie złym pomysłem w C / C ++.
Gort the Robot
1
„Ponieważ metoda zwraca tablicę” - jest to błąd w Javie, zmuszając programistów do podkręcania kodu za pomocą „Arrays.asList (x)”. T [] powinien przynajmniej zaimplementować Iterable <T>
kevin cline
4
@StevenBurnap - z pewnością jest katastrofalnie zły w C, ponieważ nie ma sposobu na skompilowanie tego kodu.
Pete Becker,
@PeteBecker Wyrażenie vector<T> x kompiluje dobrze dla mnie w C . :-)
svick
Niestety, mam na myśli C ręcznie zwijane równoważna list<T>. Zasadniczo widziałem wiele problemów z wydajnością spowodowanych przez programistów, którzy domyślnie używają list, gdy tablica była lepszym wyborem.
Gort the Robot
1

Cóż, znalazłem zastosowanie tablic w grze, którą piszę. Użyłem go do stworzenia systemu ekwipunku ze stałą liczbą miejsc. Miało to kilka zalet:

  1. Wiedziałem dokładnie, ile otwartych miejsc na ekwipunek ma obiekt gry, patrząc i sprawdzając, które są puste.
  2. Wiedziałem dokładnie, w jakim indeksie znajduje się każdy element.
  3. Wciąż była to tablica „typowana” (Inwentaryzacja przedmiotu []), więc mogłem dodawać / usuwać obiekty typu „przedmiot”.

Doszedłem do wniosku, że gdybym kiedykolwiek potrzebował „zwiększyć” rozmiar ekwipunku, mógłbym to zrobić, przenosząc stare przedmioty do nowej tablicy, ale ponieważ ekwipunek został ustalony na podstawie powierzchni ekranu i nie musiałem dynamicznie powiększać go / mniejsze, działało dobrze do celu, w którym go używałem.

Mt.
źródło
1

Jeśli przemierzasz wszystkie elementy listy, to nie, tablica nie jest potrzebna, wystarczy „następna” lub dowolna „selekcja bez zamiany”.

Ale jeśli twój algorytm potrzebuje losowego dostępu do elementów w kolekcji, to tak, potrzebna jest tablica.

Jest to w pewnym sensie analogiczne do „czy jest to konieczne?”. W rozsądnym nowoczesnym języku wcale nie jest to potrzebne. Ale jeśli zdejmiesz abstrakcje, w pewnym momencie to wszystko, co naprawdę jest dla ciebie dostępne, to znaczy, jedynym sposobem na wdrożenie tych abstrakcji jest funkcja „niepotrzebnej”. (Oczywiście analogia nie jest idealna, nie sądzę, aby ktokolwiek twierdził, że tablice są słabą praktyką programowania; są łatwe do zrozumienia i przemyślenia).

Mitch
źródło
Lista <T> oferuje również dostęp losowy. Jasne, jest zaimplementowany z tablicą, ale to nie musi przeszkadzać użytkownikowi. W najlepszym razie zaoferowałeś jeden powód używania tablic: do wdrożenia List<T>.
@delnan Myślę, że o to mi chodzi w odniesieniu do abstrakcji. Czasami lepiej jest myśleć w kategoriach tablicy, nie tylko ze względu na wydajność. (oczywiście czasami lepiej jest myśleć o połączonej liście, a znacznie lepiej niż myśleć o liście (bez dbania o linki lub w inny sposób, w jaki sposób jest ona implementowana), a o wiele lepiej po prostu kolekcję.
Mitch
0

Starsza kompatybilność.

Wszystkie tworzą osobiste doświadczenie:

Dawni programiści - mój kolega używa tablic wszędzie, robił to od ponad 30 lat, powodzenia zmieniając zdanie z twoimi nowymi wymyślonymi pomysłami.

Starszy kod - foo (pasek tablicy []) na pewno możesz użyć funkcji toarray listy / wektora / kolekcji, ale jeśli nie używasz żadnej z dodatkowych funkcji, łatwiej jest użyć tablicy na początku, często bardziej czytelnej bez zmiany typu.

Starszy szef - mój szef był dobrym programistą, zanim jeszcze wiele lat temu przeszła do zarządzania i nadal uważa, że ​​jest na bieżąco, „używając tablic” może zakończyć spotkanie, wyjaśniając, jaką kolekcję może kosztować każdy lunch.

Skeith
źródło
3
koledzy, którzy są 20 lat za zakrętem i szef, który chce wiedzieć, jakich typów danych używasz ... Uwielbiam tę witrynę, przypominając sobie, o ile gorsza może być moja praca
JoelFan
1
około 40% tego, co robimy, to projektowanie osadzone, w którym dyskusje odbywają się w KB, lubi mi mówić, że nie jest przestarzały, jest specjalistą lol
Skeith
0

1) Nie ma wielowymiarowej wersji Listy. Jeśli dane mają więcej niż jeden wymiar, używanie list będzie bardzo nieefektywne.

2) Kiedy masz do czynienia z dużą liczbą małych typów danych (powiedzmy, mapa, w której wszystko, co masz, to jeden bajt dla typu terenu), mogą występować znaczne różnice wydajności z powodu buforowania. Wersja tablicy ładuje kilka elementów na odczytaną pamięć, wersja listy ładuje tylko jeden. Ponadto wersja tablicy zawiera kilka razy więcej komórek w pamięci podręcznej niż wersja listy - jeśli wielokrotnie przetwarzasz dane, może to mieć dużą różnicę, jeśli wersja tablicy mieści się w pamięci podręcznej, ale wersja listy nie.

W skrajnym przypadku rozważ grę Minecraft. (Tak, nie jest napisane w języku C #. Dotyczy to tego samego powodu.)

Loren Pechtel
źródło
1
W rzeczywistości .Net jest pod tym względem dziwny: tablice wielowymiarowe (np. T[,]) Są wolniejsze niż równoważne tablice poszarpane (npT[][] . ) .
svick,
0

100-elementowa tablica pewnego typu T zawiera 100 niezależnych zmiennych typu T. Jeśli T jest typem wartości, który ma zmienne pole publiczne typu Q i jedno typu R, to każdy element tablicy będzie zawierał zmienne niezależne typu Q i R. Tablica jako całość będzie zatem zawierała 100 zmiennych niezależnych typu Q i 100 zmiennych niezależnych typu R; do każdej z tych zmiennych można uzyskać dostęp indywidualnie, bez wpływu na inne. Żaden typ kolekcji inny niż tablice nie pozwala na stosowanie pól struktur jako zmiennych niezależnych.

Jeśli zamiast tego T okazał się typem klasy z publicznie zmiennymi polami typu Q i R, każdy element tablicy zawiera jedyne odniesienie, w dowolnym miejscu we wszechświecie, do instancji użycia tablicy lub zbioru typu zmiennej klasy, co stwarza możliwość że zmienne identyfikowane przez elementy tablicy mogą nie być niezależne .T i, jeśli żaden z elementów tablicy nigdy nie będzie zostać zmodyfikowane w celu zidentyfikowania obiektu, do którego istnieje jakiekolwiek odniesienie zewnętrzne, wówczas tablica skutecznie obuduje 100 zmiennych niezależnych typu Q i 100 zmiennych niezależnych typu R. Inne typy kolekcji mogą naśladować zachowanie takiej tablicy, ale jeśli jest to jedyny cel tablicy służy do enkapsulacji 100 zmiennych typu Q i 100 typu R, enkapsulacja każdej pary zmiennych w obiekcie własnej klasy jest drogim sposobem na zrobienie tego. Dalej,

Jeśli typ ma zachowywać się jak jakiś obiekt, to powinien być albo typem klasy, albo strukturą pola prywatnego, która nie zapewnia żadnej innej mutacji niż zamiana. Jeśli jednak typ ma zachowywać się jak wiązka pokrewnych, ale niezależnych zmiennych sklejonych razem z taśmą klejącą, wówczas należy użyć typu, który jest wiązką zmiennych sklejonych razem z taśmą klejącą - struktura pola odsłoniętego . Tablice tego typu są bardzo wydajne w pracy i mają bardzo czystą semantykę. Użycie dowolnego innego typu doprowadzi do mętnej semantyki, gorszej wydajności lub obu.

supercat
źródło
0

Ważną różnicą jest przydział pamięci. Na przykład przeglądanie połączonej listy może spowodować wiele braków pamięci podręcznej i spowolnienie wydajności, podczas gdy tablica reprezentuje ciągłą część pamięci zawierającą wiele instancji określonego typu danych, a wykonywanie tej operacji w kolejności jest bardziej prawdopodobne, że uderzy w procesor Pamięć podręczna.

Oczywiście tablica odwołań do obiektów może nie odnieść tak dużych korzyści z trafień w pamięci podręcznej, ponieważ dereferencje mogą nadal zabrać Cię w dowolne miejsce w pamięci.

Następnie są implementacje list, takie jak ArrayList, które implementują listę za pomocą tablicy. Są to przydatne prymitywy.

Rory Hunter
źródło
2
Pytanie dotyczy w szczególności typu .Net List<T>, który nie jest zaimplementowany za pomocą listy połączonej, ale za pomocą tablicy (w zasadzie jest to odpowiednik ArrayList<T>w Javie).
svick,
-2

Oto kilka wskazówek, z których możesz skorzystać, kiedy Arrayi kiedy wybrać List.

  • Użyj, Arraygdy wracasz z metody.
  • Użyj Listjako zmiennej podczas konstruowania wartości zwracanej (wewnątrz metody). Następnie użyj, .ToArray()gdy wracasz z metody.

Ogólnie rzecz biorąc, użyj, Arraygdy nie zamierzasz dodawać produktów do kolekcji. Użyj, Listgdy zamierzasz dodać produkty do kolekcji.

Arrayjest przeznaczony do obsługi kolekcji „statycznych”, podczas gdy Listjest przeznaczony do obsługi kolekcji „dynamicznych”.

Daniel Lidström
źródło
2
Zasada, którą sugerujesz, jest arbitralna i może skutkować nieefektywnym kodem, który wykonuje niepotrzebne kopiowanie. Przynajmniej potrzebujesz jakiejś formy uzasadnienia.
Jules
@Jules Uważam, że doświadczenie programistów jest znacznie ważniejsze niż mikrooptymalizacje. Nigdy nie mam problemów z wydajnością na tym poziomie.
Daniel Lidström,
Nie widzę jednak, jak ta zasada poprawia wrażenia programistów. Wymaga to odgadnięcia, co klienci twojego kodu będą chcieli zrobić ze zwracanymi wartościami, i sprawia, że ​​kod jest mniej wygodny w użyciu, gdy się pomylisz, a mimo to nie widzę w tym żadnej korzyści. Wydajność może być kwestią drugorzędną, ale nie poświęciłbym jej, aby przestrzegać zasady, która nic nie zyskuje.
Jules
@Jules Chyba sprowadza się to do twoich własnych preferencji. Wolę traktować zwracane wartości jako stałe, jako takie wolę używać Arrayzamiast List. Miło słyszeć twoje myśli!
Daniel Lidström,
Czy rozważałeś użycie UmmodifiableLists?
Jules