using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
// Визначення перелічуваного типу Rank
public enum Rank
{
Junior,
Middle,
Senior,
Expert
}
// Інтерфейс IDateAndCopy
public interface IDateAndCopy
{
object DeepCopy();
DateTime Date { get; set; }
}
// Клас License (без змін з лабораторної роботи 2)
public class License
{
public string LicenseNumber { get; set; }
public string Category { get; set; }
public DateTime IssueDate { get; set; }
public DateTime ExpiryDate { get; set; }
public License(string licenseNumber, string category, DateTime issueDate, DateTime expiryDate)
{
LicenseNumber = licenseNumber;
Category = category;
IssueDate = issueDate;
ExpiryDate = expiryDate;
}
public override string ToString()
{
return $"License: {LicenseNumber}, Category: {Category}, Issued: {IssueDate:d}, Expires: {ExpiryDate:d}";
}
}
// Клас Person з реалізацією інтерфейсу IDateAndCopy
public class Person : IDateAndCopy, IEquatable<Person>
{
protected string firstName;
protected string lastName;
protected DateTime birthDate;
public Person(string firstName, string lastName, DateTime birthDate)
{
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate;
}
public Person() : this("John", "Doe", new DateTime(1990, 1, 1)) { }
// Властивості
public string FirstName
{
get => firstName;
set => firstName = value;
}
public string LastName
{
get => lastName;
set => lastName = value;
}
public DateTime BirthDate
{
get => birthDate;
set => birthDate = value;
}
public int BirthYear
{
get => birthDate.Year;
set => birthDate = new DateTime(value, birthDate.Month, birthDate.Day);
}
// Реалізація інтерфейсу IDateAndCopy
public DateTime Date { get; set; } = DateTime.Now;
public virtual object DeepCopy()
{
return new Person(firstName, lastName, birthDate) { Date = this.Date };
}
// Перевизначення методів Equals та GetHashCode
public override bool Equals(object obj)
{
if (obj is Person other)
return Equals(other);
return false;
}
public bool Equals(Person other)
{
if (other is null) return false;
return firstName == other.firstName &&
lastName == other.lastName &&
birthDate == other.birthDate;
}
public override int GetHashCode()
{
return HashCode.Combine(firstName, lastName, birthDate);
}
public static bool operator ==(Person left, Person right)
{
if (left is null) return right is null;
return left.Equals(right);
}
public static bool operator !=(Person left, Person right)
{
return !(left == right);
}
public override string ToString()
{
return $"{firstName} {lastName}, Born: {birthDate:d}";
}
}
// Клас Client, який успадковується від Person
public class Client : Person
{
public string IssueType { get; set; }
public DateTime DeliveryDate { get; set; }
public Client(Person person, string issueType, DateTime deliveryDate)
: base(person.FirstName, person.LastName, person.BirthDate)
{
IssueType = issueType;
DeliveryDate = deliveryDate;
}
public Client() : base()
{
IssueType = "Engine problem";
DeliveryDate = DateTime.Now;
}
public override string ToString()
{
return $"{base.ToString()}, Issue: {IssueType}, Delivery: {DeliveryDate:d}";
}
public override object DeepCopy()
{
return new Client((Person)base.DeepCopy(), IssueType, DeliveryDate);
}
}
// Клас StationWorker, який успадковується від Person
public class StationWorker : Person, IEnumerable<License>, IDateAndCopy
{
private string specialization;
private Rank rank;
private int experience;
private List<License> licenses = new List<License>();
private List<Client> clients = new List<Client>();
public StationWorker(Person person, string specialization, Rank rank, int experience)
: base(person.FirstName, person.LastName, person.BirthDate)
{
this.specialization = specialization;
this.rank = rank;
Experience = experience; // Використовуємо властивість для валідації
}
public StationWorker() : base()
{
specialization = "Mechanic";
rank = Rank.Junior;
Experience = 1;
}
// Властивості
public Person PersonData
{
get => new Person(firstName, lastName, birthDate);
set
{
firstName = value.FirstName;
lastName = value.LastName;
birthDate = value.BirthDate;
}
}
public License FirstLicense => licenses.Count > 0 ? licenses[0] : null;
public List<Client> Clients
{
get => clients;
set => clients = value ?? new List<Client>();
}
public int Experience
{
get => experience;
set
{
if (value < 0 || value > 100)
throw new ArgumentOutOfRangeException(nameof(Experience),
"Experience must be between 0 and 100 years");
experience = value;
}
}
public string Specialization
{
get => specialization;
set => specialization = value;
}
public Rank Rank
{
get => rank;
set => rank = value;
}
public List<License> Licenses
{
get => licenses;
set => licenses = value ?? new List<License>();
}
// Методи
public void AddLicense(params License[] newLicenses)
{
licenses.AddRange(newLicenses);
}
public override string ToString()
{
string licensesStr = string.Join("\n ", licenses.Select(l => l.ToString()));
string clientsStr = string.Join("\n ", clients.Select(c => c.ToString()));
return $"{base.ToString()}, Specialization: {specialization}, Rank: {rank}, " +
$"Experience: {experience} years\nLicenses:\n {licensesStr}\nClients:\n {clientsStr}";
}
public string ToShortString()
{
return $"{base.ToString()}, Specialization: {specialization}, Rank: {rank}, " +
$"Experience: {experience} years, Total Clients: {clients.Count}";
}
public override object DeepCopy()
{
var copy = new StationWorker(
(Person)base.DeepCopy(),
specialization,
rank,
experience
);
copy.licenses = licenses.Select(l => new License(l.LicenseNumber, l.Category, l.IssueDate, l.ExpiryDate)).ToList();
copy.clients = clients.Select(c => (Client)c.DeepCopy()).ToList();
return copy;
}
// Ітератори
public IEnumerable<Client> GetRepairClients()
{
foreach (var client in clients)
{
yield return client;
}
}
public IEnumerable<Client> GetClientsByIssue(string issueType)
{
foreach (var client in clients.Where(c => c.IssueType.Equals(issueType, StringComparison.OrdinalIgnoreCase)))
{
yield return client;
}
}
// Додатковий ітератор для клієнтів, які віддали авто більше місяця тому
public IEnumerable<Client> GetClientsWithOldRepairs()
{
foreach (var client in clients.Where(c => (DateTime.Now - c.DeliveryDate).TotalDays > 30))
{
yield return client;
}
}
// Реалізація IEnumerable<License> для перебору ліцензій до 2010 року
public IEnumerator<License> GetEnumerator()
{
return new StationWorkerEnumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// Допоміжний клас для перебору ліцензій до 2010 року
private class StationWorkerEnumerator : IEnumerator<License>
{
private StationWorker stationWorker;
private int currentIndex = -1;
public StationWorkerEnumerator(StationWorker sw)
{
stationWorker = sw;
}
public License Current => stationWorker.licenses[currentIndex];
object IEnumerator.Current => Current;
public bool MoveNext()
{
currentIndex++;
while (currentIndex < stationWorker.licenses.Count)
{
if (stationWorker.licenses[currentIndex].IssueDate.Year < 2010)
return true;
currentIndex++;
}
return false;
}
public void Reset()
{
currentIndex = -1;
}
public void Dispose() { }
}
}
// Головний клас програми
class Program
{
static void Main()
{
Console.WriteLine("=== 1. Перевірка рівності об'єктів Person ===");
Person person1 = new Person("Ivan", "Petrenko", new DateTime(1985, 5, 15));
Person person2 = new Person("Ivan", "Petrenko", new DateTime(1985, 5, 15));
Console.WriteLine($"References equal: {ReferenceEquals(person1, person2)}");
Console.WriteLine($"Objects equal: {person1 == person2}");
Console.WriteLine($"Hash code 1: {person1.GetHashCode()}");
Console.WriteLine($"Hash code 2: {person2.GetHashCode()}");
Console.WriteLine("\n=== 2. Створення StationWorker з ліцензіями та клієнтами ===");
StationWorker worker = new StationWorker(person1, "Engine Specialist", Rank.Senior, 10);
// Додаємо ліцензії
worker.AddLicense(
new License("LIC001", "A", new DateTime(2005, 3, 10), new DateTime(2015, 3, 10)),
new License("LIC002", "B", new DateTime(2015, 6, 20), new DateTime(2025, 6, 20))
);
// Додаємо клієнтів
worker.Clients.AddRange(new[]
{
new Client(new Person("Oleg", "Sydorenko", new DateTime(1990, 8, 12)),
"Engine failure", DateTime.Now),
new Client(new Person("Maria", "Ivanova", new DateTime(1988, 2, 25)),
"Transmission issue", DateTime.Now.AddDays(-5)),
new Client(new Person("Petro", "Koval", new DateTime(1975, 11, 3)),
"Brake system", DateTime.Now.AddMonths(-2))
});
Console.WriteLine(worker);
Console.WriteLine("\n=== 3. Властивість PersonData ===");
Console.WriteLine(worker.PersonData);
Console.WriteLine("\n=== 4. Тестування DeepCopy ===");
StationWorker copy = (StationWorker)worker.DeepCopy();
// Змінюємо оригінал
worker.FirstName = "ChangedName";
if (worker.Clients.Count > 0)
worker.Clients[0].IssueType = "ChangedIssue";
Console.WriteLine("Original after changes:");
Console.WriteLine(worker.ToShortString());
Console.WriteLine("\nCopy (should be unchanged):");
Console.WriteLine(copy.ToShortString());
Console.WriteLine("\n=== 5. Тестування валідації стажу ===");
try
{
worker.Experience = 150; // Некоректне значення
}
catch (ArgumentOutOfRangeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
}
Console.WriteLine("\n=== 6. Ітератор для клієнтів з сьогоднішньою датою ===");
Console.WriteLine("Clients with today's delivery date:");
foreach (var client in worker.GetRepairClients().Where(c => c.DeliveryDate.Date == DateTime.Today))
{
Console.WriteLine($" {client}");
}
Console.WriteLine("\n=== 7. Ітератор для клієнтів з конкретною несправністю ===");
Console.WriteLine("Clients with 'Engine failure':");
foreach (var client in worker.GetClientsByIssue("Engine failure"))
{
Console.WriteLine($" {client}");
}
Console.WriteLine("\n=== 8. Перебір ліцензій до 2000 року (IEnumerable) ===");
Console.WriteLine("Licenses issued before 2000:");
foreach (var license in worker)
{
Console.WriteLine($" {license}");
}
Console.WriteLine("\n=== 9. Клієнти з ремонтом більше місяця тому ===");
Console.WriteLine("Clients with repairs older than 1 month:");
foreach (var client in worker.GetClientsWithOldRepairs())
{
Console.WriteLine($" {client}");
}
}
}