2011-01-21 16 views
6

Czy LINQ rzeczywiście wykonuje głęboką kopię wyników do innej listy/tablicy/etc, czy po prostu daje mi listę/tablicę/etc. składa się z odniesień do oryginału?Czy nowa pamięć LINQ podczas tworzenia zwraca

+6

Nic w .NET - z wyjątkiem może serializacji - zawsze automatycznie tworzy głęboką kopię czegokolwiek. Jednym z powodów jest to, że kopie głębokie nie są trywialne do automatycznego konstruowania. – bzlm

+0

@bzlm - więc kiedy edytuję wynik zapytania LINQ, faktycznie edytuję wartość elementu z pierwotnej kolekcji? –

+0

Tak, jesteś. Spróbuj. :) – bzlm

Odpowiedz

10

To zależy od tego, czy (i jak) używasz Wybierz, aby rzutować wyniki.

Jeśli nie utworzysz nowych obiektów w rzucie, wynik odniesie te same obiekty co kolekcja oryginalna.

Jeśli jednak utworzysz nowe obiekty w projekcie, to oczywiście nie będą one takie same.

Kolekcja powrócił tu będzie zawierać odniesienia do tych samych obiektów w _myCollection:

from m in _myCollection 
where m.SomeFilterCriteria 
select m 

Zbiory powrócił w tych przypadkach nie będzie:

from m in _myCollection 
where m.SomeFilterCriteria 
select new { m.Prop1, m.Prop2 } 

W tym przypadku warto zwrócić uwagę te Prop1 i Prop2 nowego anonimowego obiektu - jeśli są to typy odniesienia - będą zawierały odniesienie do obiektu tego samego obiektu. Tylko odniesienia najwyższego poziomu w kolekcji będą różne.

Zasadniczo - nic w .Net poza serializerami (jak wspomniano tutaj w innym miejscu) będzie "głęboko" kopiować, chyba że go zaimplementujesz.

lub

from m in _myCollection 
where m.SomeFilterCriteria 
select m.Clone() 

Ponownie, byłoby błędem zakładać, że każdy „głębokie” kopiowanie tu się dzieje. Oczywiście implementacja Clone będzie w tej klasie i może być wszystkim, włączając w to głębokie kopiowanie, ale to nie jest dane.

+0

W twoim ostatnim przykładzie, myślałem, że 'Klon()' wykonał tylko płytką kopię. –

+0

Klon będzie kopiował, ale został zaimplementowany, aby to zrobić. Nie ma domyślnego .Clone - musisz go zaimplementować dla dowolnego obiektu, na którym chcesz go obsługiwać. Moja odpowiedź odnosi się tylko do referencji najwyższego poziomu w kolekcji. Nic "głębokiego" nie kopiuje w .Net. –

+1

@Joel B: Aby dodać komentarz do qstarin, [artykuł MSDN] (http://msdn.microsoft.com/en-us/library/system.icloneable.clone.aspx) stwierdza wprost, że "Klon może być zaimplementowany albo jako kopia głęboka lub płytka kopia. "Zatem nie tylko skopiuje kopię, ale została zaimplementowana, ale płytka i głęboka kopia to ** dwie ** dopuszczalne implementacje zgodnie z dokumentacją MSDN. Co ciekawe, obiekt ma chronionego członka [MemberwiseClone] (http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx) do wykonywania płytkich kopii. – Brian

2

To, co zwraca, jest bardzo zależne od metody LINQ, do której się odnosisz. Ale z wyjątkiem kilku metod, które jawnie kopiują wyliczenie (na przykład), ogólny wzorzec nie kopiuje wejścia do nowej struktury. Zamiast tego woli leniwą ocenę.

+1

Jeśli ponownie przeczytacie pytanie, okaże się, że ToList() i ToArray() nie są specjalne. :) – bzlm

+1

@bzlm, nie jestem pewien, jak pytanie jest związane z tą częścią mojej odpowiedzi. Chciałem je konkretnie nazwać 2 metodami LINQ, które chętnie oceniają dane wejściowe i tworzą dla nich nową strukturę kolekcji, zanim przedstawię szerszą wypowiedź na temat pozostałych. Nie powiedziałem, że zrobił on głęboką kopię, więc nie jestem pewien, o czym mówisz. – JaredPar

+1

@JaredPar Pytanie brzmi: "Czy LINQ rzeczywiście wykonuje głęboką kopię [...] lub czy po prostu daje mi listę [...] złożoną z odniesień do oryginału". Twoja odpowiedź dotyczy tego, czy * wyliczenia * są oceniane. Dobrze? – bzlm

3

Czy LINQ rzeczywiście wykonuje głęboką kopię wyników na inną listę/tablicę/etc, czy po prostu daje mi listę/tablicę/etc. składa się z odniesień do oryginału?

Od Enumerable.ToArray. (Tekst podobne znajdują się Enumerable.ToList)

ToArray (IEnumerable) siły Sposób natychmiastowa ocena zapytania i zwraca tablicę zawierającą wyniki zapytania. Możesz dodać tę metodę do zapytania, aby uzyskać buforowaną kopię wyników zapytania.

Cóż, to na pewno wygląda na zagmatwane.

  1. zwraca tablicę zawierającą zapytanie wyniki
  2. uzyskania buforowane kopia wyników zapytania

Od pierwszego zdania, to jest oczywiste, że nie kopie elementów w zapytaniu są wykonane.

Od drugiego zdania otrzymuje się kopię wyników zapytania jako całość, ale jest to płytka kopia od bez kopii pozycji w zapytaniu..

Powiązane problemy