擴充套件和介面一起啟用 DRY 程式碼和類似 mixin 的功能

擴充套件方法使你可以通過僅在介面本身中包含核心所需功能來簡化介面定義,並允許你將方便方法和過載定義為擴充套件方法。具有較少方法的介面在新類中更容易實現。將過載保持為擴充套件而不是將它們直接包含在介面中可以使你免於將樣板程式碼複製到每個實現中,從而幫助你保持程式碼乾燥。這實際上類似於 C#不支援的 mixin 模式。

System.Linq.EnumerableIEnumerable<T> 的擴充套件就是一個很好的例子。IEnumerable<T> 只需要實現類來實現兩個方法:泛型和非泛型 GetEnumerator()。但是 System.Linq.Enumerable 提供了無數有用的實用工具作為擴充套件,可以簡單明瞭地消費 IEnumerable<T>

以下是一個非常簡單的介面,帶有作為擴充套件提供的便利過載。

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)}");
    }
}