Considera se sarà comune avere collezioni di oggetti con diverse combinazioni di abilità e se il codice potrebbe voler eseguire un'azione su quegli elementi, all'interno di una raccolta, che lo supportano . Se è così, e se ci sarebbe un "comportamento predefinito" ragionevole per oggetti che non hanno un supporto utile per qualche azione, potrebbe essere utile avere interfacce implementate da una vasta gamma di classi, non solo quelle che possono comportarsi in modo utile.
Ad esempio, supponiamo che solo alcuni tipi di creature possano avere Woozles, e uno vuole che tali creature abbiano una proprietà NumerOfWoozles
. Se una tale proprietà fosse in un'interfaccia che è stata implementata solo da creature che possono avere Woozles, il codice che voleva trovare il numero totale di Woozles detenuti da una collezione di creature di tipi misti dovrebbe dire qualcosa del tipo:
int total = 0;
foreach (object it in creatures)
{
IWoozleCountable w = trycast(it, IWoozleCountable);
if (w != null) total += w.WoozleCount;
}
Se, comunque, WoozleCount fosse un membro di Creature / ICreature, anche se pochi sottotipi avrebbero sovrascritto l'implementazione WoozleCount predefinita di Creature che restituisce sempre zero, il codice potrebbe essere semplificato in:
int total = 0;
foreach (ICreature it in creatures)
total += it.WoozleCount;
Mentre alcune persone si irritano all'idea che ogni Creatura implementa una proprietà WoozleCount che è davvero utile solo per alcuni sottotipi, la proprietà sarebbe significativa per tutti i tipi, indipendentemente dal fatto che sarebbe utile con elementi noti per questi tipi, e considererei l'interfaccia "kitchen sink" come meno un odore di codice rispetto all'operatore trycast.