Supposons que j'ai une méthode
public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
List<User> users = new List<User>();
// some database stuff
return users;
}
J'ai lu qu'il serait préférable de renvoyer une interface (soit IList
ou IEnumerable
) plutôt que de renvoyer a List
. Certains arguments que j'ai entendus pour le faire sont qu'il cache les données et donne au développeur d'API la flexibilité de changer la représentation interne des données à une date ultérieure.
Mon souci de simplement renvoyer un IEnumerable
est que vous perdez des fonctionnalités, telles que l'accès aléatoire et la Count
propriété.
Je sais qu'accepter un IEnumerable
comme paramètre est logique, car cela donne au consommateur la meilleure flexibilité pour envoyer des données à ma méthode, l'ensemble minimaliste d'exigences pour que la méthode fonctionne.
Quelle est la meilleure pratique pour le type de retour?
la source
Réponses:
De manière générale, vous pouvez commencer par les interfaces et ne déplacer pour placer le type concret comme type de retour que si vous constatez que vous utilisez les méthodes supplémentaires plus fréquemment que prévu.
Eh bien, si vous retournez une interface, vous conservez plus de flexibilité. Vous pouvez modifier l'implémentation ultérieurement pour renvoyer un type de béton différent. D'un autre côté, cela donne évidemment à l'appelant moins d'informations, de sorte qu'il peut ne pas être en mesure d'effectuer certaines opérations. (Par exemple: si vous retournez
List<T>
, l'appelant peut utiliser ConvertAll etc ... ce qu'il ne peut pas si vous déclarez seulement que vous retournezIList<T>
.) Dans certaines situations, il convient de spécifier le type concret.Concernant la méthode Count ou Sort, il n'y a pas d'interfaces de collecte standard pour cela. Cependant, vous pouvez écrire une méthode d'extension pour trier ou compter n'importe quel IList.
la source
Si vous avez besoin que votre collection en ait une,
Count
vous pouvez l'utiliserICollection<T>
, ce qui est assez général.la source
Vous retournez ce qui est prudent pour la méthode que vous définissez. Est-ce que vous faites le retour d'une série d'articles (l'accent est mis sur les articles) ou renvoie-t-il une collection d'articles (l'accent est mis sur la collection dans son ensemble)? Vaut-il la peine de permettre des écarts dans la mise en œuvre de la collection? Si cela n'a jamais de sens d'utiliser un générateur ou
HashSet
alors utilisez simplement leList
.la source
Spécifique à l'exemple de méthode: vous avez raison de dire que le retour
IEnmuerable<T>
signifierait que vous perdriez la fonctionnalitéCount
et l'indexation (bien que vous puissiez utiliser les méthodes LINQCount()
etElementAt()
, qui sont implémentées efficacement si le type sur lequel elles sont réellement implémentéesIList<T>
).Si vous reveniez
IList<T>
, vous perdriez certaines fonctionnalités, mais le gain en général en vaut probablement la peine.Mais encore mieux serait quelque chose entre
IEnumerable<T>
etIList<T>
, car il est très peu probable que le consommateur mute la collection retournée, mais cela a du sens pour lui d'utiliserCount
ou d'indexer.Dans .Net 4.5, il y a cette interface:
IReadOnlyList<T>
.la source
IReadOnlyList
sonne bien quand je peux obtenir VS2013, merci!