Szanowni Państwo,
Mam tutaj dość prosty, acz przydługawy, program sortujący listę.
-
Metoda "sort()" ma dwa przeciążenia. Jedno z obiektem klasy która dziedziczy "IComparable<>" a drugie klasy "Comparison<>". Co nam to w sumie zmienia czy użyjemy jednego sposobu czy drugiego? czyt. która metoda jest lepsza? Oba te sposoby opierają się stworzeniu obiektu będącego delegatem?
-
Za pomocą
listPersonel.Sort(delegate (Personel c1, Personel c2) { return c1.Name.CompareTo(c2.Name); });
tworzymy obiekt (delegat) anonimowy który przekazujemy funkcji sortującej. Jakie są zalety korzystania z obiektów anonimowych? -
Jeśli użyjemy "Peek definition" na klasie "Comparision" to będziemy mieli:
public delegate int Comparison<in T>(T x, T y);
Co oznacza fragment<in T>
?
Tutaj kod programu:
using System;
using System.Collections.Generic;
namespace IntroductionIntoCsharp22
{
class Program
{
static void Main()
{
Console.WriteLine("Hello World!");
//Utworzenie listy instancji klasy Personel
List<Personel> listPersonel = new List<Personel>();
listPersonel.Add(new Personel("John", 4500));
listPersonel.Add(new Personel("Hawking", 3500));
listPersonel.Add(new Personel("Olek", 2500));
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.ID + " " + person.Name + " " + person.Salary);
}
//Posortowanie listy po zarobkach według wewnętrznej metody
listPersonel.Sort();
Console.WriteLine("\nPosortowane po zarobkach");
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.Name + " " + person.Salary);
}
//Utworzenie obiektu klasy "SortByName" i przekazanie go, jako argument, funkcji sortującej.
SortByName objekt = new SortByName();
listPersonel.Sort(objekt);
Console.WriteLine("\nPosortowane po imionach");
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.Name + " " + person.Salary);
}
//Utworzenie instancji obiektu będącego delegatem "Comparision" do porównania po zarobkach
Comparison<Personel> personelComparer = new Comparison<Personel>(ComparePersonel);
//Wywołanie funkcji sortującej listę po zarobkach
listPersonel.Sort(personelComparer);
Console.WriteLine("\nPosortowane po zarobkach");
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.ID + " " + person.Name + " " + person.Salary);
}
//Utworzenie anonimowego obiektu będącego delegatem porównującym dwa obiekty po imieniu
listPersonel.Sort(delegate (Personel c1, Personel c2) { return c1.Name.CompareTo(c2.Name); });
Console.WriteLine("\nPosortowane po imionach");
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.ID + " " + person.Name + " " + person.Salary);
}
//Utworzenie, za pomocą wyrażenia lambda, anonimowego obiektu będącego delegatem porównującym po dwa obiekty po imieniu
listPersonel.Sort((x, y) => x.ID.CompareTo(y.ID));
Console.WriteLine("\nPosortowane po ID");
//Wyświetlenie listy personelu
foreach (Personel person in listPersonel)
{
Console.WriteLine(person.ID + " " + person.Name + " " + person.Salary);
}
Console.ReadKey();
}
//Definicja, za pomocą wyrażenia lambda, klasy porównującej dwa obiekty tego samego typu po zarobkach
private static int ComparePersonel(Personel x, Personel y) => x.Salary.CompareTo(y.Salary);
}
//definicja klasy Personel
class Personel : IComparable<Personel>
{
static int Pop = 0;
public int ID { get; }
public string Name { get; }
public int Salary { get; }
public Personel(string name, int salary)
{
Pop++;
this.ID = Pop;
this.Name = name;
this.Salary = salary;
}
//Funkcja interfejsu "IComparable<>" porówująca dwa obiekty po zarobkach
public int CompareTo(Personel obj)
{
return this.Salary.CompareTo(obj.Salary);
}
}
//Definicja klasy porównująca obiekty po imieniu
class SortByName : IComparer<Personel>
{
public int Compare(Personel obj1, Personel obj2)
{
return obj1.Name.CompareTo(obj2.Name);
}
}
}