0Pricing
C# Academy · Lezione

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> implementa Compare(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>.Create collega le lambda all'interfaccia.
  • Usi IComparable per 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

  1. Implementazione di IEquatable
  2. Override di GetHashCode
  3. Implementazione di IComparable
  4. IComparer per l'ordinamento personalizzato
← Torna a C# Academy