IComparer per l'ordinamento personalizzato
Fornisca ordinamenti alternativi con i comparer.
IComparer per l'ordinamento personalizzato è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Ordinare in modi diversi
Un tipo ha un solo ordine naturale tramite IComparable<T>. Per ordinare gli stessi dati in altri modi, fornisca un oggetto IComparer<T> o un delegato Comparison<T> nel punto della chiamata.
Implementare IComparer<T>
Un IComparer<T> è un oggetto separato con un metodo Compare(x, y). Segue lo stesso contratto di CompareTo: valore negativo, zero o positivo.
using System;
using System.Collections.Generic;
public class Person
{
public string Name;
public int Age;
public Person(string name, int age) { Name = name; Age = age; }
public override string ToString() => Name + "(" + Age + ")";
}
public class ByName : IComparer<Person>
{
public int Compare(Person x, Person y)
=> string.Compare(x.Name, y.Name, StringComparison.Ordinal);
}
public class Program
{
public static void Main()
{
var people = new List<Person> { new Person("Zoe", 1), new Person("Ann", 2) };
people.Sort(new ByName());
Console.WriteLine(string.Join(", ", people));
}
}Più comparatori per un tipo
Può definire diversi comparatori e sceglierne uno per ogni ordinamento. Qui le stesse persone possono essere ordinate per nome o per età, secondo necessità.
using System;
using System.Collections.Generic;
public class Person
{
public string Name;
public int Age;
public Person(string name, int age) { Name = name; Age = age; }
public override string ToString() => Name + "(" + Age + ")";
}
public class ByAge : IComparer<Person>
{
public int Compare(Person x, Person y) => x.Age.CompareTo(y.Age);
}
public class Program
{
public static void Main()
{
var people = new List<Person> { new Person("Ann", 40), new Person("Bo", 20) };
people.Sort(new ByAge());
Console.WriteLine(string.Join(", ", people));
}
}Delegato Comparison<T>
Per ordinamenti occasionali, un delegato Comparison<T> (spesso una lambda) è più conciso di un'intera classe. List.Sort lo accetta direttamente.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var words = new List<string> { "banana", "fig", "apple" };
// Sort by length using a Comparison<string> lambda
words.Sort((a, b) => a.Length.CompareTo(b.Length));
Console.WriteLine(string.Join(", ", words));
}
}Ordinamento decrescente con un comparatore
Inverta un ordine scambiando gli operandi all'interno di Compare. In questo modo ottiene un ordinamento decrescente senza modificare il tipo.
using System;
using System.Collections.Generic;
public class DescendingInt : IComparer<int>
{
public int Compare(int x, int y) => y.CompareTo(x);
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 3, 1, 4, 1, 5 };
nums.Sort(new DescendingInt());
Console.WriteLine(string.Join(", ", nums));
}
}Comparatori in OrderBy
LINQ OrderBy accetta un IComparer<TKey> come secondo argomento, consentendo di personalizzare il confronto delle chiavi selezionate.
using System;
using System.Collections.Generic;
using System.Linq;
public class CaseInsensitive : IComparer<string>
{
public int Compare(string x, string y)
=> string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
}
public class Program
{
public static void Main()
{
var names = new[] { "bob", "Alice", "carol" };
foreach (var n in names.OrderBy(x => x, new CaseInsensitive()))
Console.WriteLine(n);
}
}Confronto su più chiavi
Un comparatore può ordinare in base a più chiavi, secondo un ordine di priorità. Calcoli la prima chiave; in caso di parità, passi a quella successiva.
using System;
using System.Collections.Generic;
public class Employee
{
public string Dept;
public int Salary;
public Employee(string dept, int salary) { Dept = dept; Salary = salary; }
public override string ToString() => Dept + ":" + Salary;
}
public class ByDeptThenSalary : IComparer<Employee>
{
public int Compare(Employee x, Employee y)
{
int byDept = string.Compare(x.Dept, y.Dept, StringComparison.Ordinal);
return byDept != 0 ? byDept : x.Salary.CompareTo(y.Salary);
}
}
public class Program
{
public static void Main()
{
var staff = new List<Employee>
{
new Employee("IT", 50), new Employee("HR", 40), new Employee("IT", 30)
};
staff.Sort(new ByDeptThenSalary());
Console.WriteLine(string.Join(", ", staff));
}
}Scorciatoia Comparer.Create
Comparer<T>.Create crea un IComparer<T> a partire da una lambda, combinando la concisione di un delegato con le API dell'interfaccia che richiedono un comparatore.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var byLengthDesc = Comparer<string>.Create((a, b) => b.Length.CompareTo(a.Length));
var words = new List<string> { "hi", "hello", "hey" };
words.Sort(byLengthDesc);
Console.WriteLine(string.Join(", ", words));
}
}Riutilizzare i comparatori tra raccolte
Una singola istanza di comparatore può gestire ordinamento, ricerca e set ordinati. Definirla una sola volta mantiene coerenti le regole di ordinamento ovunque venga utilizzata.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
IComparer<int> desc = Comparer<int>.Create((a, b) => b.CompareTo(a));
var set = new SortedSet<int>(desc) { 1, 5, 3 };
Console.WriteLine(string.Join(", ", set));
}
}Scegliere tra IComparable e IComparer
Usi IComparable<T> per l'unico ordine naturale incorporato nel tipo. Usi IComparer<T> o Comparison<T> per i numerosi ordini alternativi e specifici del contesto che decide nel punto della chiamata.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var nums = new List<int> { 5, 2, 8, 1 };
nums.Sort(); // natural ascending (int is IComparable)
Console.WriteLine(string.Join(", ", nums));
nums.Sort((a, b) => b - a); // custom descending via delegate
Console.WriteLine(string.Join(", ", nums));
}
}Provi autonomamente
Ordini un elenco in tre modi diversi usando comparatori e una lambda, senza modificare il tipo degli elementi.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var words = new List<string> { "pear", "fig", "apple", "kiwi" };
words.Sort(); // natural alphabetical
Console.WriteLine(string.Join(", ", words));
words.Sort((a, b) => a.Length.CompareTo(b.Length)); // by length
Console.WriteLine(string.Join(", ", words));
words.Sort(Comparer<string>.Create((a, b) => b.CompareTo(a))); // reverse alphabetical
Console.WriteLine(string.Join(", ", words));
}
}Controllo rapido
Scelga l'astrazione corretta per l'ordinamento.
Riepilogo
L'ordinamento personalizzato usa comparatori forniti nel punto della chiamata.
IComparer<T>implementaCompare(x, y)con il contratto di valore negativo, zero o positivo.- I delegati
Comparison<T>e le lambda sono adatti agli ordinamenti occasionali. Comparer<T>.Createcollega le lambda all'interfaccia.- Usi
IComparableper l'ordine naturale e i comparatori per quelli alternativi.
Domande Frequenti
La lezione «IComparer per l'ordinamento personalizzato» è gratuita?
Sì — il testo completo di «IComparer per l'ordinamento personalizzato» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «IComparer per l'ordinamento personalizzato»?
Fornisca ordinamenti alternativi con i comparer. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «IComparer per l'ordinamento personalizzato»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Implementazione di IEquatable
- Override di GetHashCode
- Implementazione di IComparable
- IComparer per l'ordinamento personalizzato