In thinking about the principle of "be conservative in what you send and liberal in what you accept", I generally try to make my methods receive
IEnumerable parameters, but emit a
IReadOnlyCollection (except where deferred execution is truly valuable, then I do emit an
However, I just realized that when specifying methods in an interface, this may be reversed. Is that true?
Should my interface specifications be telling any implementers "I'll give you an
IReadOnlyCollection, but you can just give me any old
IEnumerable back"? (Again, if deferred execution makes sense, I would provide an
IEnumerable as a parameter type instead.) This makes those methods the reverse, accepting a narrow/conservative set but emitting a broad/liberal one. However, this seems right to me because with the dependency inversion, in reality the input arguments when the method is called are really the output arguments of the core system (specifying the interface).
I'm just wondering if my thinking is right on this or not. It seems that making the implementer side as easy as possible is really where the benefit is.
I'm realizing that part of the issue comes from my concern about not requiring implementers to think deeply about whether deferred execution makes sense or not. Knowing when an enumerable will be enumerated can be very important in a system, and with the separation of concerns that an interface can help bring to code, I wouldn't want to be so liberal in what the interface method outputs (which is ultimately an input to the core system) that improperly-deferred
IEnumerables get thrown around...
This is not about speed. Not sure why this was raised, but please do not even think for a second about performance implications here. That is not the question.