Как загрузить данные в класс и отсортировать их

#c# #winforms

#c# #winforms

Вопрос:

Существует LoadStudents метод, который записывает объекты с некоторыми полями в массив Student классов. Необходимо разработать метод (я попробовал, вызвал его Add ), с помощью которого можно будет выполнить эту процедуру, используя три TextBoxes и код для кнопки, которая сохранит эти данные.

 public partial class Form1 : Form
{
    public static int k=0;
    Student[] mas = new Student[3];
    public Form1()
    {
        InitializeComponent();
    }
    public delegate int CompareHealth(Student o1, Student o2);
    public class Student
    {
        public string name = "";
        public int days = 0;
        public int hemoglobin = 0;
        public Student() { }
        public Student(string name, int days, int hemoglobin)
        {
            this.name = name;
            this.days = days;
            this.hemoglobin = hemoglobin;
        }
        public Student(Student s)
        {
            name = s.name;
            days = s.days;
            hemoglobin = s.hemoglobin;
        }
        public string add
        {
            set { name = value; }
            get { return name; }
        }

        private static int CompareName(Student o1, Student o2)
        {
            return (string.Compare(o1.name, o2.name));
        }

        private static int CompareDays(Student o1, Student o2)
        {
            if (o1.days > o2.days) return (1);
            else if (o1.days < o2.days) return (-1);
            else return (0);
        }
        private static int CompareHemoglobin(Student o1, Student o2)
        {
            if (o1.hemoglobin > o2.hemoglobin) return (1);
            else if (o1.hemoglobin < o2.hemoglobin) return (-1);
            else return (0);
        }
        public static CompareHealth SortByName { get { return (new CompareHealth(CompareName)); } }
        public static CompareHealth SortByDays { get { return (new CompareHealth(CompareDays)); } }
        public static CompareHealth SortByHemoglobin { get { return (new CompareHealth(CompareHemoglobin)); } }
    }
    class Students
    {
        private int items = 0; const int n = 10;
        private Student[] students = new Student[n];
        public Student this[int num]
        {
            get { return (students[num - 1]); }
            set { (students[num - 1]) = value; }
        }
        public void Vivod(ListBox h)
        {
            for (int i = 0; i < items; i  )
            {
                h.Items.Add(students[i].name   " "   students[i].days   " "   students[i].hemoglobin   " ");
            }
        }
        public void LoadStudents()
        {
            Student p = new Student("А", 13, 68);
            students[items  ] = p;
            Student w = new Student("Б", 18, 67);
            students[items  ] = w;
            Student e = new Student("В", 5, 75);
            students[items  ] = e;
        }
        public void Add(TextBox t1, TextBox t2, TextBox t3)
        {
            if (k < 3)
            {
                Student load = new Student();
                students[items  ] = load;
                k  ;
            }
        }
        public void SortStudent(CompareHealth compare)
        {
            Student temp = new Student();
            for (int i = 1; i < items; i  )
                for (int j = items - 1; j >= i; j--)
                    if (compare(students[j], students[j - 1]) == -1)
                    { temp = students[j - 1]; students[j - 1] = students[j]; students[j] = temp; }
        }
    }
private void button2_Click(object sender, EventArgs e)
    {
        listBox1.Items.Clear();
        Students students = new Students();
        students.SortStudent(Student.SortByName);
        students.Vivod(listBox1);
    }
private void button1_Click(object sender, EventArgs e)
    {
        Students students = new Students();
        students.Add(textBox1, textBox2, textBox3);
    }
  

Проблема в том, что одна кнопка содержит Add метод, а другая (сортировка), опять же, нужно указать ссылку на объект students и, как я понимаю, массив сбрасывается. Как правильно писать код для кнопок?

Комментарии:

1. Вы должны сохранить объект students как переменную класса, вместо того, чтобы создавать новую при каждом нажатии кнопки. Таким образом, они не будут очищены и сброшены при нажатии кнопки Добавить.

2. @Jon Ты это серьезно? Students students = new Students(); Что я могу изменить в коде моего button2, чтобы не сбрасывать?

3. Поместите Students students; в начало вашего класса Form с другими переменными класса. Затем в вашей кнопке вы можете просто получить к нему доступ с помощью this.students . Вы также захотите поместить LoadStudents(); в конструктор формы.

4. @Jon public partial class Form1 : Form { Students students = new Students(); ...... private void button1_Click(object sender, EventArgs e) { this.students.Add(textBox1, textBox2, textBox3); this.students.Vivod(listBox1); } Нравится это? Это не работает

5. Да, это сработает

Ответ №1:

Я попытался переписать ваши классы, чтобы они были немного более идиоматичными. Дайте мне знать, если здесь есть что-нибудь, для чего вам нужно какое-то объяснение.

 public partial class Form1 : Form
{
    private Students _students = new Students();
    public Form1()
    {
        InitializeComponent();
    }
    private void button2_Click(object sender, EventArgs e)
    {
        _students.Sort(Students.SortByName);
        this.Vivod(listBox1);
    }
    private void button1_Click(object sender, EventArgs e)
    {
        _students.Add(new Student(textBox1.Text, int.Parse(textBox2.Text), int.Parse(textBox3.Text)));
    }
    private void Vivod(ListBox listBox)
    {
        listBox.Items.Clear();
        listBox.Items.AddRange(_students.ToStrings());
    }
}

public class Students
{
    private int _items = 0;
    private const int __n = 10;
    private Student[] students = new Student[__n];
    public Student this[int num]
    {
        get => students[num - 1];
        set { (students[num - 1]) = value; }
    }
    public string[] ToStrings() => Enumerable.Range(0, _items).Select(i => students[i].ToString()   " ").ToArray();
    public void LoadStudents()
    {
        this.Add(new Student("А", 13, 68));
        this.Add(new Student("Б", 18, 67));
        this.Add(new Student("В", 5, 75));
    }
    public void Add(Student load)
    {
        if (_items < __n)
        {
            students[_items  ] = load;
        }
    }
    public void Sort(IComparer<Student> comparer)
    {
        Array.Sort(students, comparer);
    }
    private class SortByNameComparer : IComparer<Student>
    {
        public int Compare(Student o1, Student o2) => string.Compare(o1.Name, o2.Name);
    }
    private class SortByDaysComparer : IComparer<Student>
    {
        public int Compare(Student o1, Student o2) => o1.Days > o2.Days ? 1 : (o1.Days < o2.Days ? -1 : 0);
    }
    private class SortByHemoglobinComparer : IComparer<Student>
    {
        public int Compare(Student o1, Student o2) => o1.Hemoglobin > o2.Hemoglobin ? 1 : (o1.Hemoglobin < o2.Hemoglobin ? -1 : 0);
    }
    public static IComparer<Student> SortByName => new SortByNameComparer();
    public static IComparer<Student> SortByDays => new SortByDaysComparer();
    public static IComparer<Student> SortByHemoglobin => new SortByHemoglobinComparer();    
}

public class Student
{
    public string Name { get; set; } = "";
    public int Days { get; set; } = 0;
    public int Hemoglobin { get; set; } = 0;
    public Student() { }
    public Student(string name, int days, int hemoglobin)
    {
        this.Name = name;
        this.Days = days;
        this.Hemoglobin = hemoglobin;
    }
    public Student(Student s) : this(s.Name, s.Days, s.Hemoglobin) { }
    public override string ToString() => $"{this.Name} {this.Days} {this.Hemoglobin}";
}
  

В идеале я бы сделал Student inherit from List<Student> , чтобы получить встроенные операции со списком. В качестве альтернативы я бы использовал List<Student> вместо Student[] inside Students . Но это должно быть хорошим началом.