Obiekty a obsługa zdarzeń

0

Witam,
Chciałem zrobić prostą aplikację na WindowsForm, która ma działać w ten sposób:
[button] - tworzy nowy obiekt: listę
[click]-[click]-[click] dodaje wartości x-y klikniętych punktów do listy

Pytanie: dlaczego tablica waypoints "does not exists in current context" skoro jest zadeklarowana w [main] ?

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Point[] waypoints = new Point[3];
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            waypoints[Count.no].loc_x = MousePosition.X;
            waypoints[Count.no].loc_y = MousePosition.Y;
        }

        private void Button_Click(object sender, EventArgs e)
        {
            waypoints[Count.no] = new Point();
            Count.no = +1;
        }
    }

    public class Point
    {
        public int loc_x;
        public int loc_y;
    }

    public static class Count
    {
        public static int no = 0;
    }
0

Nie wdając się w szczegóły: zmienne istnieją tylko w obrębie klamerek. Więc tworzysz w kontruktorze formy Form1 sobie zmienną waypoints, a kiedy konstruktor się kończy, to zmienna przestaje istnieć.

Musisz ja zrobić jako zmienną składową twojej klasy:

    public partial class Form1 : Form
    {
        Point[] waypoints;

        public Form1()
        {
            InitializeComponent();
            waypoints = new Point[3];
        }
0

Zrób tak

public partial class Form1 : Form
    {
		Point[] waypoints = new Point[3];

        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Click(object sender, EventArgs e)
        {
            waypoints[Count.no].loc_x = MousePosition.X;
            waypoints[Count.no].loc_y = MousePosition.Y;
        }
 
        private void Button_Click(object sender, EventArgs e)
        {
            waypoints[Count.no] = new Point();
			if (Count.no < 2)
			{
            	Count.no++; // popraw!
			}
        }
    }
 
    public class Point
    {
        public int loc_x;
        public int loc_y;
    }
 
    public static class Count
    {
        public static int no = 0;
    }
0

Hmm... w obu przypadkach aplikacja się wywala na linijce:
waypoints[Count.no].loc_x = MousePosition.X;
"odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu"
Jest to o tyle dziwne, iż kod który w zasadzie wygląda identycznie, a na którym się wzorowałem
https://4programmers.net/Forum/Newbie/207010-tworzenie_obiektow_za_pomoca_petli
działa poprawnie.

0

bo array jest nullem (musisz stworzyc obiekty recznie), nie baw sie w array i skorzystaj z List<Point> Przy zderzeniu wykorzystaj funkcje add

0

Pytanie dla lepszego zrozumienia:

Tworzę "ręcznie" nowy obiekt poprzez Klasa nazwa = new Klasa(); - zawsze bolała mnie ta nazwa jako "fizyczny" adres obiektu.
Za pomocą listy (a konkretnie: nazwa_listy.Add(new Klasa {...}) mogę za pomocą pętli niemal błyskawicznie stworzyć niemal nieograniczoną ilość obiektów klasy.

Pytanie nowicjusza:
Jak to się dzieje że w pierwszym przypadku MUSZĘ zadeklarować nazwę obiektu, a w przypadku listy już nie? Jaka jest różnica?

1

Żadna, tak naprawdę :)

Tłumacząc nie do końca dokładnie, ale na zrozumienie idei:
W obu wypadkach tworzysz obiekt - czyli rezerwujesz sobie miejsce w pamięci, odpalasz konstruktor, ustawiasz wartości i tak dalej. Wywołanie new zwraca ci adres tego nowo stworzonego obiektu - i jeżeli robisz konstrukcję postaci:

var x = new Obiekt();

To zapisujesz ten adres do zmiennej o nazwie x.

Z kolei robiąc:

lista.Add(new Obiekt());

Ten adres też jest zwracany - ale przekazywany do metody Add() listy lista i on sobie wewnętrznie gdzieś go wykorzystuje. Fakt, że nie ma jawnie widocznej i nazwanej zmiennej określającej ten nowy obiekt nie oznacza, że jej tam wcale nie ma.

1

mozesz tez zrobic tak

var x = new Obiekt();
lista.Add(x);

jest to rownoznaczne jakbys tworzyl obiekt w Add

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