C# - beznadziejny błąd z jagged array.

0

Witam.
Od razu proszę kod:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MooShuu
{
    public class Program
    {
        private static void Main(string[] args)
        {
            string[][] s = new string[3][];
            string[] s1 = new string[3];
            s1[0] = "0";
            s1[1] = " ";
            s1[2] = "0";
            s[0] = s1;
            s[1] = s1;
            s[2] = s1;
            s[1][2] = "@";


            foreach (var item in s)
            {
                foreach (var i in item)
                {
                    Console.Write(i);
                }
                Console.WriteLine();
            }
            Console.Read();
        }
    }
}

Więc dlaczego po przejściu przez:

s[1][2] = "@";

program nadaje wartość "@" każdej tablicy w s ? Przeciez podaje index 1... Wiem można to zroibc inaczej ale potzrebuje takiego rozwiązania do mojego programu, a nie wiem dlaczego tak się dzieje i to mnie martwi, proszę o pomoc.

OUTPUT tego programu:

0 @
0 @
0 @

Output który chce uzyskać:

0 0
0 @
0 0

Z góry dziękuje,
Ellyon

2

Hint: Jak zamienimy linijkę:

s[1][2] = "@";

na

s1[2] = "@";

to efekt będzie ten sam dlaczego? :>

0

Chce uzyskać:

0 0
0 @
0 0

A nie to samo..
Zamienie tych linijek nic nie zmieni, w końcu podmieniam wartość w tablicy której następnie używam w jagged array s ..

2

Tablicy s nie masz w trzech kopiach, tylko w jednej, bo przypisanie jej do kolejnych komórek tablicy nie rozmnaża przypisywanego obiektu. Skoro obiekt tablicy s nie jest kopiowany, to wszędzie masz referencje do niej. Reszta jest już tylko konsekwencją tego.

0
ŁF napisał(a):

Tablicy s nie masz w trzech kopiach, tylko w jednej, bo przypisanie jej do kolejnych komórek tablicy nie rozmnaża przypisywanego obiektu. Skoro obiekt tablicy s nie jest kopiowany, to wszędzie masz referencje do niej. Reszta jest już tylko konsekwencją tego.

Dziękuje za odp, możesz dać jakieś rozwiązanie ? Bo dalej nie wiem jak sobie z tym poradzić ;x

2

Problem jest taki, że masz przypisany ten sam obiekt w trzy różne miejsca w tablicy, więc jak zmienisz jakiś element to zmieni się cała reszta, która wskazuje na ten obiekt. Jest to całkowicie poprawne. Nie wiem jakie Ty masz zadanie, bo jeśli chodzi o sam output to równie dobrze możesz dać:

 s[1] = new string[] {"0", "@", "0"};

co spowoduje stworzenie nowej tablicy stringów i przypisze jej referencje do s[1]. Jednak nie wiem po co przypisujesz je właśnie w ten sposób, więc nie wiem czy to rozwiązanie będzie dla Ciebie dobre.

0
mefmund napisał(a):

Problem jest taki, że masz przypisany ten sam obiekt w trzy różne miejsca w tablicy, więc jak zmienisz jakiś element to zmieni się cała reszta, która wskazuje na ten obiekt. Jest to całkowicie poprawne. Nie wiem jakie Ty masz zadanie, bo jeśli chodzi o sam output to równie dobrze możesz dać:

 s[1] = new string[] {"0", "@", "0"};

co spowoduje stworzenie nowej tablicy stringów i przypisze jej referencje do s[1]. Jednak nie wiem po co przypisujesz je właśnie w ten sposób, więc nie wiem czy to rozwiązanie będzie dla Ciebie dobre.

Dziękuje za odpowiedź, dzięki niej uzyskałem już pożądany efekt.
Takiego rozwiązania jak pokazałem w pierwszym poście potrzebuje ponieważ robię grę tekstową w konsoli. A rozmiar mapy jest podawany przez gracza wiec musi być ona tworzona podczas wykonywania programu, więc rozwiązanie:

s[1] = new string[] {"0", "@", "0"};

Nie przyda mi się bo sam nie wiem jaki gracz poda rozmiar mapy. Program tworzy kontury mapy "0", a w środku daje " " po których porusza się gracz, więc po prostu mam przykładową tablice "s" (z " " w srodku i "0" na końcu i początku która oczywiście tworze in run time odnosząc się do podanych wymiarów mapy ) którą wypełniam moją mapę ( jagged array). Dlatego potem gdy chce dodawać jakiś nowy element mapy musze używać np.

s[1][2] = "@";

Ellyon

1

Dlatego każdy wiersz tabelki 2D musi być zainicjowany odrębnym, nowym obiektem. Możesz to też zrobić w pętli.

0
ŁF napisał(a):

Dlatego każdy wiersz tabelki 2D musi być zainicjowany odrębnym, nowym obiektem. Możesz to też zrobić w pętli.

Tak też robię. Dziękuje wszystkim, topic rozwiązany.

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