2016-04-13 11 views
5

Patrząc na implementację List.AddRange znalazłem coś dziwnego, którego nie rozumiem. Sourcecode, see line 727 (AddRange wzywa InsertRange)Listę <T> .AddRange/InsertRange tworzenie tymczasowej tablicy

T[] itemsToInsert = new T[count]; 
c.CopyTo(itemsToInsert, 0); 
itemsToInsert.CopyTo(_items, index); 

Dlaczego czynisz to Skopiuj kolekcji w "Temp-tablicy" (itemsToInsert), a następnie kopiuje tablicy temp do rzeczywistego _items-tablicy? Czy istnieje jakikolwiek powód tego, lub jest to tylko niektóre z pozostałości kopiowania źródła ArrayList, ponieważ to samo dzieje się tam.

+2

Założę się, że należy przekazywać elementy przez wartość zamiast przez odniesienie, tak aby wstawiane oryginalne elementy nie były modyfikowane w przypadku, gdy same elementy na liście zostały zmodyfikowane. –

+1

@Jdsfighter - Nie rozumiem, jak to pomaga w ogóle. Zawartość tablicy lub kolekcji to wartości lub odwołania. Powyższy kod nie zmienia charakteru kopiowanych treści. –

+0

Naprawdę nie sądzę, że chodzi o ukrywanie podstawowej tablicy. W mojej odpowiedzi wskazałem inne prawdopodobne wyjaśnienie. – Fabjan

Odpowiedz

4

Domyślam się, że ma to na celu ukrycie istnienia wewnętrznej tablicy podkładu. Nie ma sposobu na uzyskanie odniesienia do tej tablicy, która jest zamierzona. Klasa List nawet nie obiecuje, że istnieje taka tablica. (Oczywiście, ze względu na wydajność i ze względu na kompatybilność, zawsze będzie zaimplementowana z tablicą).

Ktoś może przekazać w stworzonym ICollection<T>, który pamięta tablicę, która została przekazana. Teraz osoby dzwoniące mogą zadzierać z wewnętrzną tablicą List i zacząć w zależności od wewnętrznych elementów List.

Porównaj to z MemoryStream, który ma udokumentowany sposób dostępu do wewnętrznego bufora (i zastrzel się nim): GetBuffer().

+0

Jeśli to jest faktyczny powód, to tak naprawdę nie widzę sensu: ktoś mógłby również użyć odbicia, aby wyszukać prywatne pola tablic, jeśli chcą zepsuć rzeczy. –

+0

Używając odbicia możesz podważyć wszystko, ale to jest trudniejsze i zdarza się rzadziej w praktyce. Wydaje się, że jest to ochrona przed przypadkowym lub niedbałym niewłaściwym korzystaniem z interfejsu API. Kod wywołania niezmiennie zaczyna zależeć od niezmienników, które obecnie są prawdziwe, ale nie są gwarantowane. Im trudniejsze, tym rzadsze będzie to. – usr

+1

Tworzenie kolekcji, która zapamiętuje tablice z zamiarem zmieszania z wewnętrznymi, nie jest dużo bardziej powszechne, powiedziałbym. Taki sam zamiar, a nie coś, co, jak sądzę, jest warte ochrony przed biblioteką ogólnego przeznaczenia. EDYCJA: Rozumiem, to chroni przed pewnym przypadkowym niewłaściwym użyciem. Nie tak daleko idące po tym wszystkim, ile danych jest używanych. –