Consider whether it will be common to have collections of objects with different combinations of abilities, and whether code might want to perform an action upon those items, within a collection, that support it. If so, and if there would be a sensible "default behavior" for objects which don't have useful support for some action, it may be helpful to have interfaces implemented by a wide range of classes, not just those that can behave usefully.
For example, suppose only a few kinds of creature can have Woozles, and one wants such creatures to have a NumerOfWoozles
property. If such a property were in an interface that were only implemented by creatures that can have Woozles, then code which wanted to find the total number of Woozles held by a collection of creatures of mixed types would have to say something like:
int total = 0;
foreach (object it in creatures)
{
IWoozleCountable w = trycast(it, IWoozleCountable);
if (w != null) total += w.WoozleCount;
}
If, however, WoozleCount were a member of Creature/ICreature, even though few subtypes would override Creature's default WoozleCount implementation that always returns zero, the code could be simplified to:
int total = 0;
foreach (ICreature it in creatures)
total += it.WoozleCount;
While some people might chafe at the idea of having every Creature implement a WoozleCount property that's really only useful for a few subtypes, the property would be meaningful for all types, whether or not it would be useful with items known to be of those types, and I would regard the "kitchen sink" interface as being less of a code smell than the trycast operator.
IEnumerable
,IEquatable
, etc.