Progettazione di interfacce
Nota
Questo contenuto viene ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms and Patterns for Reusable .NET Libraries, 2nd Edition. Tale edizione è stata pubblicata nel 2008 e il libro è stato completamente rivisto nella terza edizione. Alcune informazioni in questa pagina potrebbero non essere aggiornate.
Sebbene la maggior parte delle API siano modellate meglio usando classi e struct, esistono casi in cui le interfacce sono più appropriate o sono l'unica opzione.
CLR non supporta l'ereditarietà multipla, ad esempio le classi CLR non possono ereditare da più classi di base, ma consente ai tipi di implementare una o più interfacce oltre a ereditare da una classe di base. Pertanto, le interfacce vengono spesso usate per ottenere l'effetto di più ereditarietà. Ad esempio, IDisposable è un'interfaccia che consente ai tipi di supportare l’eliminabilità indipendentemente da qualsiasi altra gerarchia di ereditarietà in cui desiderano partecipare.
L'altra situazione in cui la definizione di un'interfaccia è appropriata consiste nella creazione di un'interfaccia comune che può essere supportata da diversi tipi, inclusi alcuni tipi di valore. I tipi valore non possono ereditare da tipi diversi da ValueType, ma possono implementare interfacce, pertanto l'uso di un'interfaccia è l'unica opzione per fornire un tipo di base comune.
✔️ Definire un'interfaccia se è necessario che alcune API comuni siano supportate da un set di tipi che include tipi valore.
✔️ È consigliabile definire un'interfaccia se è necessario supportarne la funzionalità sui tipi che ereditano già da un altro tipo.
❌ EVITARE l'uso di interfacce marcatori (interfacce senza membri).
Se è necessario contrassegnare una classe come una caratteristica specifica (marcatore), in generale, usare un attributo personalizzato anziché un'interfaccia.
✔️ SPECIFICARE almeno un tipo che è un'implementazione di un'interfaccia.
In questo modo è possibile convalidare la progettazione dell'interfaccia. Ad esempio, List<T> è un'implementazione dell'interfaccia IList<T>.
✔️ FORNIRE almeno un'API che utilizza ogni interfaccia definita (un metodo che accetta l'interfaccia come parametro o una proprietà tipizzata come interfaccia).
In questo modo è possibile convalidare la progettazione dell'interfaccia. Ad esempio, List<T>.Sort usa l'interfaccia System.Collections.Generic.IComparer<T>.
❌ NON aggiungere membri a un'interfaccia fornita in precedenza.
In questo modo si interromperebbero le implementazioni dell'interfaccia. È consigliabile creare una nuova interfaccia per evitare problemi di controllo delle versioni.
Ad eccezione delle situazioni descritte in queste linee guida, è consigliabile, in generale, scegliere classi anziché interfacce nella progettazione di librerie riutilizzabili di codice gestito.
Parti protette da copyright © 2005, 2009 Microsoft Corporation. Tutti i diritti sono riservati.
Ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2a edizione di Krzysztof Cwalina and Brad Abrams, pubblicato il 22 ottobre 2008 da Addison-Wesley Professional nella collana Microsoft Windows Development Series.