how to decide on api signature
Many times while writing functions that accept enumerable types I face this confusion. Which api exposed will be better from the following options:
public void Resolve(Func<bool>[] howtos)
public void Resolve(IEnumerable<Func<bool>> howtos)
public void Resolve(List<Func<bool>> howtos)
I usually decide based on the following: if the input needs to be modified by adding or deleting items then use List else use IEnumerable. Not sure about Array option.
Are there other points that need to be considered while deciding on the api to be exposed? Are there any rule of thumb that clearly identified situations in which on should be preferred over the o开发者_Python百科ther?
Thanks
You should always accept the least restrictive parameter types.
That means IEnumerable<T>
, ICollection<T>
, or IList<T>
.
This way, the client is free to pass any kind of implementation, such as an array, HashSet<T>
, or ReadOnlyCollection<T>
.
Specifically, you should take an IEnumerable<T>
if you only need to iterate the data, ICollection<T>
if you also want to add or remove items, or if you need to know the size, and IList<T>
if you need random access (the indexer).
The primary factor for me in making this decision is
What is Resolve actually doing with the collection?
If Resolve is not mutating the collection in any way then I would absolutely prefer the IEnumerable<Func<bool>>
signature. It allows for the greatest number of use cases and most accurately expresses the intent of the API. I for one would assume that anything taking a more concrete type like List<T>
was intending to modify the passed in collection. Seeing IEnumerable<T>
gives me a bit of assurance that the collection is simply being enumerated.
If Resolve is mutating the collection then I would prefer the List<T>
signature to indicate that a mutation was indeed possible. Our possibly I would create a fluent interface by taking and returning IEnumerable<T>
. Which would depend a lot on the type of method Resolve was. It's hard to generalize when I would choose one over the other.
Your way sounds good. The only thing I'd change is having it be IList<T>
instead of List<T>
. Allowing the user to for example validate whatever you're adding to the list.
精彩评论