简体   繁体   中英

Interface method's parameter types and return types

I have some question about what should the parameter type should be in interface methods and what should the return type be - when working with collections in C#.

Let's say I want to get a collection of A's and return a collection of B's. I know there are thumb rules that we should always get the most generic type possible and return the most specific type. So here's and example:

public interface A
{
   B[] MyMethod(IEnumerable<A> myAs);
}

Here are the questions I get from this line:

  1. When the interface is internal to the my system - should I return an interface for the B collection or concrete?
  2. Is an array return type better then a list return type?
  3. Should the myAs parameter be the most generic interface type that I need, meaning if in my code, myAs is actually a list, should the parameter be IEnumerable, ICollection or IList?

Thanks

I know there are thumb rules that we should always get the most generic type possible and return the most specific type.

No no no. Absolutely not.

The right rule of thumb is that you require the smallest possible contract from your caller , and you provide the smallest acceptable contract to your caller .

The former is for the convenience of your caller, who should not be required to meet a contract that you don't need them to meet. The latter rule ensures your ability to change your implementation details; by returning the minimum acceptable interface the implementer of the interface can pick the implementation details that are most efficient for their implementation choices.

When the interface is internal to the my system - should I return an interface for the B collection or concrete?

You return the smallest acceptable contract for the caller . Does the caller require a ReadOnlyCollection because they need to index it but not write it? Do they require an array because they need to index it and write it but not change its size? Do they require a list because they need to index it, write it, and change its size? Or do they require simply that the collection be enumerable ?

How do you know what the caller requires? You ask the developers who are going to write the call sites . They are your customers, so you gather requirements from them before you write them your method.

If there are services that they don't require then don't provide them , because providing those unnecessary services comes at a cost . Don't make your callers bear a cost from which they derive no benefit! And don't make implementers of your interface have to provide implementations of unnecessary services.

Is an array return type better then a list return type?

An array is better than a list if the caller requires mutation of contents but not mutation of size. But both are pretty lousy. Does the caller really require indexing and mutation? Most callers don't. Better would be to return an IEnumerable and then the caller can call ToArray or ToList on it if they want an array or list.

Most of the time the sensible thing to do is to just return a sequence. The caller can decide if they want to take on the enormous memory expense of realizing a sequence into a list or array.

Should the myAs parameter be the most generic interface type that I need, meaning if in my code, myAs is actually a list, should the parameter be IEnumerable, ICollection or IList?

It should be the smallest thing that an implementation of MyMethod can use . If MyMethod mutates the collection on behalf of the caller then you have to accept an IList. If it doesn't, then don't ask for a service that you're not going to use; that just makes it harder on the caller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM