lista tablic

0

Mam listę tablic. Proszę o wyjaśnienie dlaczego przy dodawaniu tablicy do listy mamy sytuację że na liście nie tworzą się kopie tych tablic.

        static List<int[]> temp = new List<int[]>();
        static int[] e = new int[2];

        e[0] = 10;
        e[1] = 20;
        temp.Add(e);
        e[0] = 5;
        e[1] = 7;
        temp.Add(e);

Zaobserwowałem że na liście zamiast tablic {10, 20} i {5, 7} mamy dwie tablice takie same , tj. tablice {5, 7}. Dlaczego? I co zmodyfikować aby na liście były obie wprowadzone tablice?

0

nadpisujesz tą samą tablice. Zrob dwie: e[0]=10; e[1]=20; f[0]=5; f[1]=7;

2

Utwórz drugą tablicę, zamiast nadpisywać wartości w pierwszej.

        int[] e = new int[2];
        e[0] = 10;
        e[1] = 20;
        temp.Add(e);

        int[] f = new int[2];
        f[0] = 5;
        f[1] = 7;
        temp.Add(f);

Jeśli wartości znasz z góry możesz zainicjować całą listę tak:

static List<int[]> temp = new List<int[]> { new[]{ 10, 20 }, new[]{ 5, 7 } };
0

Wiem że nadpisuję, ale myślałem że jeśli nadpiszę tablicę to nie nadpiszę tablicy uprzednio dodanej do listy...
To dla mnie jasne że przy utworzeniu drugiej tablicy to zadziała, ale chciałbym mieć możliwość wykorzystania tej samej statycznej tablicy (ponieważ część programu wiele razy operuje na niej) ale zarazem muszę na liście mieć to co włożyłem. A nie że jak zmienię tablicę "e" to na liście mi się też zmienia... Jak to osiągnąć i dlaczego na liście są dwie te same jeśli przecież w chwili gdy na listę ładowałem to ładowałem coś innego...

Deklaracja musi być taka :

        static List<int[]> temp = new List<int[]>();
        static int[] e = new int[2];

a rezultat taki jak napisałem. Jak to osiągnąć Panowie?

3

Tablica to typ referencyjny. Gotowe rozwiązanie napisał Ci Azarien. Jeżeli chcesz stosować tylko jedną zmienną przetrzymującą referencje do tablicy możesz to zrobić w ten sposób:

	e[0] = 1;
	e[1] = 2;
	temp.Add(e);
	e = new int[2];
	e[0] = 3;
	e[1] = 4;
	temp.Add(e);
0

Dzięki, tego szukałem.

0

Poczytaj sobie co to są typy referencyjne . W zmiennej e znajduje sie referencja (odniesienie do obiektu ) , który znajduje się na zarządzanej stercie .
Referencja to coś podobnego do wskaźnika w kodzie niezarządzanym . Obiekty na stercie przemieszczają się np. po odśmiecaniu . Można co prawda zrobić wskaźnik do obiektów o stalym rozmiarze w kntekście słowa kluczowego fixed , który zapobiega przemieszczaniu się obiektów.

0

Panowie, dzięki za wyjaśnienie. Wszystko jasne, czytałem i rozumiem. Niemniej jednak chciałem jeszcze dopytać, czy prawdą na 100% jest że w chwili wywołania metody "Add" na mojej liście do listy dodana będzie na koniec referencja do obiektu a nie sam obiekt? Jeśliby dodana byłaby głęboka kopia obiektu to powinna tam być a tymczasem odnosząc się do tego elementu listy widać że jest on inny niż był wcześniej, a zatem wyciągam wniosek że do listy dodana została referencja a nie głęboka kopia obiektu. Czy mam rację?

0

Twoja lista może zawierać wyłącznie referencje do tablic typu int . Lista<T> to jest typ generyczny z jednym parametrem typu.
Gdyby twoja lista miała parametr typu - Object to mógłbyś w niej wszystko przechowywać : referencje do obiektów różnych klas , struktury
tylko to się wiąże w przypadku struktur z pakowaniem i rozpakowywaniem . W uproszczeniu można powiedzieć , że struktury są przechowywane na stosie a typy referencyjne na stercie . Jak pakujesz to robiona jest kopia struktury i umieszczana jest na stercie . Rozpakowujesz to robiona jest odwrotna operacja .
Tego powinno się unikać

Możesz zrobić głęboką kopię tablicy ale musisz utworzyć za każdym razem nową tablicę - nowy obiekt za pomocą operatora new. Obiekty istnieją dopóki istnieje do nich referencja .
Referencja może mieć wiele kopi w rożnych zmiennych

1
Zimny Krawiec napisał(a):

W uproszczeniu można powiedzieć , że struktury są przechowywane na stosie a typy referencyjne na stercie

To nie jest uproszczenie tylko nieprawda i zbędna komplikacja.

0

Panowie, wszystko już jest jasne. Dzięki za wyjaśnienia.
Czyli wszystko co dziedziczy po System.Object oraz System.String będzie dodawane do listy jako referencja bo jest typem referencyjnym, a takie rzeczy jak struktury i zmienne "proste" będą przekazywane po wartości a zatem tworzona jest kopia zmiennej/struktury (w przypadku struktury głęboka kopia) i to właśnie ta kopia jest dodawana do listy.
Tak to rozumiem teraz.

1

Kiedyś już to wyjaśniałem ale wyjaśnię to jeszcze raz dla początkujących , których nie stać na książki co gdzie jest przechowywane

Zmienne lokalne
a) - przechowujące egzemplarze typów wartościowych są przechowywane na stosie
b) - przechowujące referencje do typów referencyjnych są przechowywane na stosie
Pola
a) - pola struktur przechowujące referencje do typów referencyjnych lub egzemplarze typów wartościowych są przechowywane na stosie
b) - pola klas przechowujące referencje do typów referencyjnych lub egzemplarze typów wartościowych są przechowywane są na stercie
Parametry
a) - parametry funkcji przechowujące referencje do typów referencyjnych lub egzemplarze typów wartościowych są przechowywane na stosie.
Elementy tablic
a) elementy tablic przechowujące referencje do typów referencyjnych lub egzemplarze typów wartościowych
są przechowywane na stercie

1 użytkowników online, w tym zalogowanych: 0, gości: 1