
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
delegate KeyValuePair<TKey, TValue> GenerateElement<TKey, TValue>(int j);
delegate TKey KeySelector<TKey>(Student st);
delegate void StudentsChangedHandler<TKey>(object source, StudentsChangedEventArgs<TKey> args);
Interface iDateAndCopy
{
object DeepCopy();
DateTime Date { get; set; }
}
[Serializable]
class Person : IDateAndCopy
{
protected string name;
protected string surname;
protected DateTime dateOfBirth;
public Person(string name, string surname, DateTime dateOfBirth)
{
this.name = name;
this.surname = surname;
this.dateOfBirth = dateOfBirth;
}
public Person()
{
name = "Name";
surname = "Surname";
dateOfBirth = DateTime.Today;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string Surname
{
get
{
return surname;
}
set
{
surname = value;
}
}
public DateTime Date
{
get
{
return dateOfBirth;
}
set
{
dateOfBirth = value;
}
}
public int YearOfBirth
{
get
{
return dateOfBirth.Year;
}
set
{
dateOfBirth = new DateTime(value, dateOfBirth.Month, dateOfBirth.Day);
}
}
public override string ToString()
{
return $"Фамилия, имя: {surname} {name}\nДата рождения: {dateOfBirth.ToShortDateString()}";
}
public virtual object DeepCopy()
{
Person human = new Person();
human.name = name;
human.surname = surname;
human.dateOfBirth = dateOfBirth;
return human;
}
}
enum Education
{
Specialist,
Bachelor,
SecondEducation
}
public enum Action
{
Add,
Remove,
Property
}
[Serializable]
class Exam : IComparable, IComparer<Exam>
{
public string subject { get; set; }
public int grade { get; set; }
public DateTime examDate { get; set; }
public Exam(string subject, int grade, DateTime examDate)
{
this.subject = subject;
this.grade = grade;
this.examDate = examDate;
}
public Exam()
{
subject = "Subject";
grade = 0;
examDate = DateTime.Today;
}
public override string ToString()
{
return $"Предмет: {subject}, Оценка: {grade}, Дата экзамена: {examDate.ToShortDateString()}";
}
// сравнивает текущий экземпляр класса Exam с переданным объектом
public int CompareTo(object obj)
{
Exam anotherSubject = obj as Exam;
return subject.CompareTo(anotherSubject.subject);
}
// сравнивает два экземпляра класса Exam на основе их оценки
public int Compare(Exam gradeOne, Exam gradeTwo)
{
if (gradeOne.grade > gradeTwo.grade)
return 1;
if (gradeOne.grade < gradeTwo.grade)
return -1;
else
return 0;
}
}
// сравнивает два экземпляра класса Exam на основе их даты экзамена
class ExamDateCompare : IComparer<Exam>
{
public int Compare(Exam dateOne, Exam dateTwo)
{
if (dateOne.examDate > dateTwo.examDate)
return 1;
if (dateOne.examDate < dateTwo.examDate)
return -1;
else
return 0;
}
}
[Serializable]
class Student : Person, IDateAndCopy, IEnumerable, INotifyPropertyChanged
{
Education formOfEducation;
int groupNumber;
List<Test> tests;
List<Exam> exams;
public event PropertyChangedEventHandler PropertyChanged;
public Student(Person human, Education formOfEducation, int groupNumber)
{
this.Name = human.Name;
this.Surname = human.Surname;
this.Date = human.Date;
this.formOfEducation = formOfEducation;
this.groupNumber = groupNumber;
tests = new List<Test>();
exams = new List<Exam>();
}
public Student()
{
//Person human = new Person();
formOfEducation = Education.Bachelor;
groupNumber = 0;
tests = new List<Test>();
exams = new List<Exam>();
}
public Person StudentData
{
get
{
return new Person(this.Name, this.Surname, this.Date);
}
set
{
this.Name = value.Name; this.Surname = value.Surname; this.Date = value.Date;
}
}
public double AverageGrade
{
get
{
if (exams.Count == 0)
{
return 0;
}
double sum = 0;
foreach (Exam exam in exams)
{
sum += exam.grade;
}
return sum / exams.Count;
}
}
public Education FormOfEducation
{
get
{
return formOfEducation;
}
set
{
formOfEducation = value;
//OnPropertyChanged("FormOfEducation");
//PropertyChanged.GetInvocationList();
//проверка на определение обработчика
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FormOfEducation"));
}
}
public int GroupNumber
{
get
{
return groupNumber;
}
set
{
if (value <= 100 || value > 599)
{
throw new ArgumentOutOfRangeException("Номер группы должен быть в диапазоне от 101 до 599");
}
else
{
groupNumber = value;
//OnPropertyChanged("GroupNumbe");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("GroupNumber"));
}
}
}
public List<Exam> Exams
{
get
{
return exams;
}
set
{
exams.AddRange(value);
}
}
public List<Test> Tests
{
get
{
return tests;
}
set
{
tests.AddRange(value);
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
//PropertyChangedEventHandler handler = PropertyChanged; // обработчик изменения свойств
//if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); // проверка на подписку
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void AddExams(params Exam[] newExams)
{
foreach (Exam exam in newExams)
{
exams.Add(exam);
}
}
public void AddTests(params Test[] newTests)
{
foreach (Test test in newTests)
{
tests.Add(test);
}
}
public override string ToString()
{
Console.WriteLine($"Студент:\n{name} {surname} {dateOfBirth},\nОбразование: {formOfEducation},\nНомер группы: {groupNumber},\nЭкзамены: ");
for (int i = 0; i < exams.Count; i++)
{
Console.WriteLine(exams[i]);
}
Console.WriteLine("Зачёты: ");
for (int i = 0; i < tests.Count; i++)
{
Console.WriteLine(tests[i]);
}
return " ";
}
public virtual string ToShortString()
{
return $"Студент:\n{name} {surname} {dateOfBirth},\nОбразование: {formOfEducation},\nНомер группы: {groupNumber},\nСредний балл: {AverageGrade}\n";
}
public override object DeepCopy()
{
Student human = new Student();
human.name = name;
human.surname = surname;
human.dateOfBirth = dateOfBirth;
human.formOfEducation = formOfEducation;
human.groupNumber = groupNumber;
foreach (Exam exam in this.exams)
{
human.Exams.Add(exam);
}
foreach (Test test in this.tests)
{
human.Tests.Add(test);
}
return human;
}
public Student DeepCopySerialization()
{
MemoryStream stream = new MemoryStream(); //создание потока для временного хранения сериализованных данных
try
{
BinaryFormatter formatter = new BinaryFormatter(); //объект для сериализации и дессериалиции объектов
formatter.Serialize(stream, this); //текущий экзепляр класса сериализуется и записывается в поток
stream.Position = 0; //позиция потока на 0 для считывания данных
var student = (Student)formatter.Deserialize(stream); //десериализация данных из потока
//stream.Close();
return student;
}
catch
{
Console.WriteLine();
Console.WriteLine("Проблемы при сериализации!");
throw new Exception();
}
finally
{
stream.Close();
}
}
public bool Save(string filename)
{
Stream file = null; //переменная для работы с файлом
if (File.Exists(filename)) //проверка на существование файла
{
try
{
file = File.Open(filename, FileMode.Create); //открытие файла с удалением содержимого
BinaryFormatter formatter = new BinaryFormatter(); //объект для сериализации и дессериалиции объектов
formatter.Serialize(file, this);
//file.Close();
return true;
}
catch
{
Console.WriteLine("Проблемы с сохранением в файл: " + filename);
//file.Close();
return false;
}
finally
{
file.Close();
}
}
else
{
try
{
file = File.Create(filename); //создание файла
file.Close();
file = File.Open(filename, FileMode.Create);
BinaryFormatter converter = new BinaryFormatter();
converter.Serialize(file, this);
//file.Close();
return true;
}
catch
{
Console.WriteLine("Проблемы с сохранением в созданный файл: " + filename);
//file.Close();
return false;
}
finally
{
file.Close();
}
}
}
public bool Load(string filename)
{
Stream file = null;