problem z zapisem obiektów do tablicy

0

witam, mam pewien problem. Mianowicie, muszę zrobić zadanie i niby je zrobiłem, błędów nie ma, jednak wyświetla mi złe wyniki. Są 2 klasy, 1 to samochód, a 2 to garaz, który ma zapisywać określoną liczbę samochodów w garażu. obiekty ma przechowywać tablica, jednak działa to źle. klasa garaż wygląda tak:

using System;
using System.Collections.Generic;
using System.Text;

namespace poo1
{
    class Garaz
    {
        public string adres;
        public int pojemnosc;
        private int liczbaSamochodow = 0;
        private Samochod[] samochody;

        public Garaz()
        {
            adres = "nieznany";
            pojemnosc = 0;
            samochody = null;
        }
        public Garaz(string adres, int pojemnosc)
        {
            this.adres = adres;
            this.pojemnosc = pojemnosc;
            Samochod[] samochody = new Samochod[pojemnosc];
        }
      
        public int Pojemnosc
        {
            get { return pojemnosc; }
            set
            {
                pojemnosc = value;
                samochody = new Samochod[pojemnosc];
            }
        }
        public string Adres
        {
            get { return adres; }
            set { adres = value; }
        }


        public void WprowadzSamochod(Samochod samochod)
        {
            samochody = new Samochod[pojemnosc];
            if (liczbaSamochodow >= pojemnosc)
            { Console.WriteLine("Garaż jest pełny"); }
            else
            {
                samochody[liczbaSamochodow] = samochod;
                liczbaSamochodow = liczbaSamochodow++;

            }
        }
        public Samochod WyprowadzSamochod()
        {
            if (liczbaSamochodow==0)
            {Console.WriteLine("Garaz jest pusty"); }
            else if (liczbaSamochodow >= pojemnosc)
            {
                samochody[liczbaSamochodow - 1] = null;
                
               
                liczbaSamochodow--;
                
            }

            return new Samochod();
        }
        public void WypiszInfo()
        {
            
            foreach (Samochod auto in samochody)
            {
                Console.WriteLine(auto);
            }
        }
    }
}

Testuję ją takim kodem:

            Samochod s1 = new Samochod("Fiat", "126p", 2, 650, 6.0);
            Samochod s2 = new Samochod("Syrena", "105", 2, 800, 7.6);
            Garaz g1 = new Garaz();
            g1.Adres = "ul. Garażowa 1";
            g1.Pojemnosc = 1;
            Garaz g2 = new Garaz("ul. Garażowa 2", 2);
            g1.WprowadzSamochod(s1);
            g1.WypiszInfo();
            g1.WprowadzSamochod(s2);
            g2.WprowadzSamochod(s2);
            g2.WprowadzSamochod(s1);
            g2.WypiszInfo();

            g2.WyprowadzSamochod();
            g2.WypiszInfo();

            g2.WyprowadzSamochod();
            g2.WyprowadzSamochod();
            Console.ReadKey();




            Console.ReadKey();

Problem jest taki, że nie wyświetla w ogóle elementów s2, a jedynie s1, s1, pusty, s1, pusty, pusty. Czy mógł by ktoś naprowadzić w gdzie robię błąd?

1
/* ... */
        public void WprowadzSamochod(Samochod samochod)
        {
            samochody = new Samochod[pojemnosc]; // co to robi? / po co to tu?
            /* ... */
        }
/* ... */
0

@Patryk27: Inicjuje tablicę, bo bez tego wyskakiwał błąd braku inicjacji. Być może zrobiłem to źle, ale nie wiem jak inaczej.

3

Problem polega na tym, że ta instrukcja za każdym razem tworzy nową, pustą tablicę - tj. każde wywołanie WprowadzSamochod() usuwa wszystkie poprzednie samochody (jak już mogłeś zaobserwować).

Zamiast tablicy, najlepiej byłoby wykorzystać kolekcję - np. List<Samochod> - ponieważ one są automatycznie-rosnące (nie trzeba ich inicjować na konkretną pojemność).

0

@Patryk27: Gdy próbuję to wpisać bez new lub w jakiś inny sposób wyrzuca błędy, a z listy nie mogę korzystać, w zadaniu mam określone, że musi to być tablica.

0

@kuku4321:

a czy przypadkiem nie wywala ci błędu przy tym obiekcie, który jest tworzony tym konstruktorem?

public Garaz()
{
	adres = "nieznany";
	pojemnosc = 0;
	samochody = null;
}
0

@WeiXiao: Nie, tylko w metodzie WprowadzSamochod

0

@kuku4321:

Gdy próbuję to wpisać bez new lub w jakiś inny sposób wyrzuca błędy, a z listy nie mogę korzystać, w zadaniu mam określone, że musi to być tablica.

no dlatego, że tu masz zmienna lokalna

Samochod[] samochody = new Samochod[pojemnosc];

tutaj

public Garaz(string adres, int pojemnosc)
{
	this.adres = adres;
	this.pojemnosc = pojemnosc;
	Samochod[] samochody = new Samochod[pojemnosc];
}
1

Taka mała uwaga do pól w klasie Garaż. Pola są publiczne a potem do nich są dodane właściwości. Właściwości są po to aby to przez nie mieć dostęp do prywatnych pól (można w nich ewentualnie sprawdzić czy ktoś nie podaje błędnych danych przy ustawianiu pola). Lepiej by było to zrobić tak:

private string adres;
public string Adres
        {
            get { return adres; } //ewentualnie get => adres;
            set { adres = value; }
        }

Bo tak to po co mi Adres i jego get jak równie dobrze mogę wartość wziąć bezpośrednio z pola adres, bo jest publiczne. W Visual Studio nawet jak wpiszesz propfull (Code Snippets) naciśniesz dwa razy Tab to wygeneruje Ci właściwość z prywatnym polem.

0

@Abachaczi: mają być prywatne tylko pod wplywem frustracji gdy nie wychodziło zmieniłem szukając źródła problemu i zapomniałem zmienić z powrotem, dzięki

0

@WeiXiao: no tam, ale gdy w metodzie nie dodam tego to wuyskakuje błąd braku inicjacji

0

@kuku4321:

a poprawiłeś ten kod w public Garaz(string adres, int pojemnosc)?

Nie inicjalizujesz tam tablicy private Samochod[] samochody;, a tworzysz zmienną lokalną.

0

@WeiXiao: zamiast tego napisałem w konstruktorze Samochod[] auta = samochody, ale nadal nie działa

2

W konstruktorze tworzysz zmienną lokalną Samochod[] a powinieneś po prostu zrobić tak : this.samochody = new Samochody[pojemnosc]. Wyżej w konstruktorze w taki sposób ustawiasz pola nie inaczej powinno tutaj. W metodzie wprowadź samochód tworzysz znowu tablicę za pomocą new. Po co? Przecież już masz tablicę, stworzyłeś ją w konstruktorze (lub w secie przy konstruktorze bezparametrowym).
liczbaSamochodow = liczbaSamochodow++; tu powinno być po prostu liczbaSamochodow++, doczytaj o preinkrementacji i postinkrementacji chyba, że to jakaś pomyłka mała bo później liczbaSamochodow
-- masz ok. W foreach jak wypisujesz auta to może wywalać błąd jak trafi na null więc ja bym dodał if(auto==null) to po prostu return; Dobrze jakbyś jeszcze przeciążył ToString() i w foreach wypisywał auto.ToString() to ładnie wyświetli informacje o samochodzie.

class Garaz
    {
        private string adres;
        private int pojemnosc;
        private int liczbaSamochodow = 0;
        private Samochod[] samochody;

        public Garaz()
        {
            adres = "nieznany";
            pojemnosc = 0;
            samochody = null;
        }
        public Garaz(string adres, int pojemnosc)
        {
            this.adres = adres;
            this.pojemnosc = pojemnosc;
            this.samochody = new Samochod[pojemnosc];
        }

        public int Pojemnosc
        {
            get { return pojemnosc; }
            set
            {
                pojemnosc = value;
                samochody = new Samochod[pojemnosc];
            }
        }
        public string Adres
        {
            get { return adres; }
            set { adres = value; }
        }

        public void WprowadzSamochod(Samochod samochod)
        {
            if (liczbaSamochodow >= pojemnosc)
            { 
                Console.WriteLine("Garaż jest pełny"); 
            }
            else
            {
                samochody[liczbaSamochodow] = samochod;

                liczbaSamochodow++;
                
            }
        }

        public void WyprowadzSamochod()
        {
            if (liczbaSamochodow == 0)
            { 
                Console.WriteLine("Garaz jest pusty"); 
            }
            else 
            {
                samochody[liczbaSamochodow-1] = null;
                liczbaSamochodow--;
                Console.WriteLine("Wyprowadzaono samochod.");
            }
        }

        public void WypiszInfo()
        {

            foreach (Samochod auto in samochody)
            {
                if (auto == null)
                {
                    return;
                }
                else 
                {
                    Console.WriteLine(auto.ToString());
                }
               
            }
        }
    }

Ja to poprawiłem tak i chyba jest okej ale nie znam treści zadań i wymagań.

0

@Abachaczi: liczbasamochodow to w wybik tego że mi to zakreslalo w wyjątku i kombinowałem, poprawione, przeciążenie jest w klasie samochód. Poprawiłem wszystko tak jak napisales, ale nadal nie działa, wyświetla tylko że garaż jest pełny

0

Pokaż swoją metode Main() co w niej masz.

0

@Abachaczi: wszystko co jest w main wkleilem w pierwszym poscie, to gotowy kod do testowania z zadania

1

Przekleiłem 1 do 1 Twojego Maina i działa jak należy z moim kodem który wkleiłem. Nie wiem gdzie może być problem xd. Do g1 o pojemności 1 jest dwa razy g1.WprowadzSamochod() więc za drugim razem wyświetli, że garaż jest pełny a w g2 wprowadzasz 2 auta do garażu o pojemności 2 i wyprowadzasz 3 razy (za trzecim razem pokaże, że garaż jest pusty)

0

@Abachaczi: Gdzieś musiałem zrobić literówkę, bo faktycznie po przeklejeniu a nie tylko dopisaniu wszystko działa, bardzo dziękuję.

0

A tak nie byłoby prościej (pomijając użycie polskich nazw)?

    class Garaz
    {
        private List<Samochod> samochody = new List<Samochod>();
        private int pojemnosc;
        public int Pojemnosc
        {
            get { return pojemnosc; }
            set
            {
                if (value < samochody.Count)
                    throw new ArgumentException("Nie można ustawić pojemności garażu na mniejszą, niż ilość aktualnie znajdujących się w nim samochodów");
                pojemnosc = value;
            }
        }
        public string Adres { get; }

        public Garaz(string adres, int pojemnosc)
        {
            Adres = adres;
            Pojemnosc = pojemnosc;
        }

        public void WprowadzSamochod(Samochod samochod)
        {
            if (samochody.Count >= pojemnosc)
                throw new Exception("Garaż jest pełny");

            samochody.Add(samochod ?? throw new ArgumentNullException(nameof(samochód)));
        }

        public void WyprowadzSamochod()
        {
            if (!samochody.Any())
                throw new Exception("Garaż jest pusty");

            samochody.Remove(samochody.Last());
        }

        public void WypiszInfo() => samochody.ForEach(a => Console.WriteLine(a.ToString()));
    }

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