Metodą ToString i tablicą obiektów

0

Witam, jak sprawnie wyświetlić obiekty tablicy(Studenta) nadpisując metodę ToString(). VS zwraca błąd: "Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu." Jak to rozwiązać ?

 class Student
    {
        private string imię;
        private string nazwisko;
        private string dataUrodzenia;
        private int numerAlbumu;

        public Student(string imię, string nazwisko, string dataUrodzenia, int numerAlbumu)
        {
            this.imię = imię;
            this.nazwisko = nazwisko;
            this.dataUrodzenia = dataUrodzenia;
            this.numerAlbumu = numerAlbumu;
        }
        public override string ToString()
        {
            return imię + " | " + nazwisko + " | " + dataUrodzenia + " | " + numerAlbumu;
        }
    }

    class Grupa
    {
        private string nazwa;
        private Student[] studenci;

        public Grupa(string nazwa, Student[] studenci)
        {
            this.nazwa = nazwa;
            this.studenci = new Student[studenci.Length];
        }
        public override string ToString()
        {
            string a = "";
            for (int i = 0; i < this.studenci.Length; i++)
            {
                Student A = studenci[i];
                a += A.ToString() + "/n";
            }
            return nazwa + "\n" + a;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Student A = new Student("XXX", "XXX", "555", 66666);
            Student B = new Student("YYY", "YYY", "444", 77777);

            Student[] studenci = new Student[2] { A, B };

            Grupa Testowa = new Grupa("Testowa", studenci);
            Console.WriteLine(Testowa.ToString());
            Console.ReadKey();
        }
    }
2

W konstruktorze klasy Grupa nadpisujesz przekazywaną tablice studenci na pustą tablice o tym samym rozmiarze.
A więc nie:

this.studenci = new Student[studenci.Length];

powinno byćthis.studenci = studenci;

0

W konstruktorze klasy grupa tworzysz nową tablicę studentów ale jej nie inicjalizujesz = zawiera same nulle
Dodaj

  Array.Copy(studenci, this.studenci, studenci.Count());

do konstruktora.
Cały kod:

 class Grupa
    {
        private string nazwa;
        private Student[] studenci;

        public Grupa(string nazwa, Student[] studenci)
        {
            this.nazwa = nazwa;
            this.studenci = new Student[studenci.Length];
            Array.Copy(studenci, this.studenci, studenci.Count());
        }
        public override string ToString()
        {
            string a = "";
            for (int i = 0; i < this.studenci.Length; i++)
            {
                Student A = studenci[i];
                a += A.ToString() + "/n";
            }
            return nazwa + "\n" + a;
        }
    }
0

Dziękuję bardzo.

0
this.studenci = new Student[studenci.Length]; 

operator new zasugerował mi że autor chce uniezależnić grupę od przekazanej tablicy studentów;P

3

Zamiast używać obleśnej konkatenacji lepiej użyć string.Format:

public override string ToString()
{
    return string.Format("{0} | {1} | {2} | {3}", this.imię, this.nazwisko, this.dataUrodzenia, this.numerAlbumu);
}

Zamiast używać tym bardziej obleśnej i niewydajnej konkatenacji w pętli lepiej użyć StringBuilder:

public override string ToString()
{
    var sb = new StringBuilder();
    sb.AppendLine(this.nazwa);
    foreach (var student in this.studenci)
    {
        sb.AppendLine(student.ToString());
    }
    return sb.ToString();
}

I nie ma sensu wołać ToString w Console.WriteLine, wystarczy po prostu:

Console.WriteLine(grupaTestowa);
0

A nie lepiej całość zrobić mniej więcej tak:

    using System;
    using System.Collections.Generic;

    public class Program
    {
        public static void Main(string[] args)
        {
            var grupaTestowa = new Grupa{Nazwa = "Testowa"};
            grupaTestowa.Add(new Student { Imie = "XXX", Nazwisko = "XXX", DataUrodzenia = "555", NumerAlbumu = 66666 });
            grupaTestowa.Add(new Student { Imie = "YYY", Nazwisko = "YYY", DataUrodzenia = "444", NumerAlbumu = 77777 });

            Console.WriteLine(grupaTestowa);
            Console.ReadLine();
        }
    }

    public class Student
    {
        public string Imie { get; set; }
        public string Nazwisko { get; set; }
        public string DataUrodzenia { get; set; }
        public int NumerAlbumu { get; set; }

        public override string ToString()
        {
            return string.Format("{0}|{1}|{2}|{3}", this.Imie, this.Nazwisko, this.DataUrodzenia, this.NumerAlbumu);
        }
    }

    public class Grupa : List<Student>
    {
        public string Nazwa { get; set; }

        public override string ToString()
        {
            return string.Format("{0}\n{1}", this.Nazwa, string.Join("\n", this));
        }
    }

Pozdrawiam,

mr-owl

P.S. Osobiście darowałbym sobie polskie nazwy klas i obiektów

2

Publiczne właściwości do zapisu mają sens tylko dla obiektów typu DTO. Tutaj tworzymy jakąś domenę, więc obiekty powinny być hermetyczne.
Jeszcze mniej sensu ma tworzenie klas domenowych poprzez dziedziczenie z klas będących implementacjami kolekcji, czyli w tym przykładzie tworzenie Grupy, która dziedziczy z List. Jaki sens mają dla Grupy wszystkie metody dostępne w List? Klasy domenowe mogą używać klas implementacyjnych, ale na pewno nie powinny być nimi.

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