C# Language Le estensioni e le interfacce insieme abilitano il codice DRY e le funzionalità di mixin-like


Esempio

I metodi di estensione consentono di semplificare le definizioni dell'interfaccia includendo solo le funzionalità essenziali richieste nell'interfaccia stessa e consentendo di definire metodi di convenienza e sovraccarichi come metodi di estensione. Le interfacce con meno metodi sono più facili da implementare nelle nuove classi. Mantenere sovraccarichi come estensioni piuttosto che includerli nell'interfaccia consente di risparmiare direttamente dal codice copiato in ogni implementazione, aiutandoti a mantenere il tuo codice ASCIUTTO. Questo in effetti è simile al pattern di mixin che C # non supporta.

System.Linq.Enumerable estensioni di System.Linq.Enumerable a IEnumerable<T> sono un ottimo esempio di ciò. IEnumerable<T> richiede solo che la classe di implementazione implementa due metodi: GetEnumerator() generico e non generico GetEnumerator() . Ma System.Linq.Enumerable fornisce innumerevoli utilità utili come estensioni che consentono un consumo conciso e chiaro di IEnumerable<T> .

Quanto segue è un'interfaccia molto semplice con sovraccarichi di comodità forniti come estensioni.

public interface ITimeFormatter
{
   string Format(TimeSpan span);
}

public static class TimeFormatter
{
    // Provide an overload to *all* implementers of ITimeFormatter.
    public static string Format(
        this ITimeFormatter formatter,
        int millisecondsSpan)
        => formatter.Format(TimeSpan.FromMilliseconds(millisecondsSpan));
}

// Implementations only need to provide one method. Very easy to
// write additional implementations.
public class SecondsTimeFormatter : ITimeFormatter
{
   public string Format(TimeSpan span)
   {
       return $"{(int)span.TotalSeconds}s";
   }
}

class Program
{
    static void Main(string[] args)
    {
        var formatter = new SecondsTimeFormatter();
        // Callers get two method overloads!
        Console.WriteLine($"4500ms is rougly {formatter.Format(4500)}");
        var span = TimeSpan.FromSeconds(5);
        Console.WriteLine($"{span} is formatted as {formatter.Format(span)}");
    }
}