7
votes

Retourner iEnumerable avec "tolistasync ()" à l'intérieur de la méthode

Actuellement, je travaille avec le code d'autre. Et ce n'est pas la première fois que je vois quelque chose comme ceci:

public async MyMethod Task<IEnumerable<MyResult>> FindResults()
{
// some code here
var ret = await repository.BusinessObjects.ToListAsync()

return ret;

}


1 commentaires

Envisagez de lire cette idée d'obtenir ce que iList , iEnumerable et icollection Claudiobernasconi.ch/2013/07/22/...


3 Réponses :


0
votes

Cela dépend de votre cas d'utilisation. IEnumerable fournit une meilleure abstraction, mais cela peut certainement venir avec des coûts de performance en fonction de votre utilisation.

C'est vrai que vous iriez une fois pour créer la liste ASYNC et (potentiellement) itérer à nouveau comme un consommateur de l'énumérable.

I Personnellement (pour mon étui d'utilisation), utilisez le motif que vous avez montré uniquement dans des chemins critiques non performants par exemple. Initialisation


0 commentaires

0
votes

n'est-il pas contre-productif d'utiliser iEnumerable dans MyMethod Type de retour car le résultat a déjà été décidé et il vaut mieux le garder de cette façon? Ne serait-il pas préférable d'utiliser list ?

Je ne vois pas comment cela ferait une différence ou pourquoi c'est un problème. Habituellement, le problème est que lorsque vous retournez une collection paresseuse (comme une requête EF), où plusieurs itérations à ce sujet entraînent plusieurs appels de base de données.

Vous retournez une liste , et de sorte que plusieurs itérations ne sont pas une préoccupation. Si vous voulait retourner list pour préciser l'appelant qu'il est prudent à itérer plusieurs fois, c'est bien, mais cela ne change vraiment rien.

Il y a d'autres avantages pour renvoyer un type de base plus (par exemple, il vous permet de renvoyer différents types de collecte autres que Liste ) mais dans le contexte de votre préoccupation concernant plusieurs énumérations, si le type de retour est list ou iEnumerable n'a pas d'importance.


5 commentaires

Utilisation iEnumerable L'interface ne contient pas ajouter () ou supprimer () méthode. S'assurer que votre collection ne sera pas modifiée en passant entre plusieurs couches. Dans la liste ou iEnumerable La requête est déjà matérialisée. Il suffit de retourner l'interface la plus basse n'est pas une bonne chose? Si ma méthode renvoie ilist i peut retourner list ou tableau . Si nous retournons la liste , nous nous programmons plutôt sur la mise en œuvre de la mise en œuvre.


@Eldho True, cela changerait ce que le client pourrait faire avec la collection retournée, mais je pense que la préoccupation de l'OP n'était pas si énumérée plusieurs fois, ce qui n'est pas une préoccupation énorme avec la liste .


Oui dans cette liste de contexte devrait être le meilleur pari


@Eldho doit être clair, je ne dis pas que le retour est meilleur; Je dis que de ce point de vue (multiples itérations) peu importe . Il y a d'autres avantages pour retourner un type de base plus, mais ils ne s'appliquent pas aux préoccupations de la question. Je vais ajouter ça à ma réponse alors c'est plus clair.


Merci, je reçois peu de biaise.



7
votes

Techniquement, il n'y a aucun problème à écrire du code de cette façon. Dans votre exemple de code spécifique ci-dessus, cela n'a pas d'importance (techniquement) si vous retournez une liste list <> , mais le type de retour de la méthode est ienumerable <> . Il n'y a pas de succès de performance, le type de retour réel est toujours une liste <> .

qui étant dit que ce n'est pas une bonne pratique. Il existe une directive de conception qui indique que vous devez structurer vos méthodes pour toujours renvoyer le type le plus spécifique possible et Accepter le type le plus générique / abstrait possible ( dans les limites de bien sûr, vous ne devez pas prendre objet. En tant que paramètre pour chaque méthode ).

Voir cet article intitulé renvoie le type le plus spécifique, accepte le type le plus générique par Vladimir Khorikov comme référence. Cela a également été demandé à ce sujet, voir est-il préférable de renvoyer le type le plus spécifique ou le plus général d'une méthode d'action? .

Cela signifie donc que les 2 signatures suivantes seraient bonnes pratiques (en utilisant votre exemple) en supposant que la 1ère signature a Liste est le type retourné et dans Le 2e exemple que tout ce qui est en train de faire la mise à jour, doit simplement itérer sur l'entrée. xxx


3 commentaires

D'accord en principe, mais pas à l'étendue du retour d'une liste , car cela vous empêchera de modifier votre définition de méthode pour renvoyer un type de collecte différent (tel que Observablecollection ) sans casser les consommateurs. Il est préférable de récupérer iList (ou icollection ).


@Douglas - Je pense que nous sommes tous les deux d'accord. S'il est possible pour une signature de méthode (via une interface ou un autre type) pour renvoyer quelque chose d'autre comme (à l'aide de votre exemple) Observablecollection <> alors vous êtes 100% correct, un iliste <> < / Code> serait le meilleur choix de type de retour, car il s'agit du type le plus spécifique entre Observablecollection <> et Liste <> (si c'était l'autre possibilité). Donc, le principe ci-dessus serait toujours valide. De plus, je pense que beaucoup de fois les interfaces seraient toujours le meilleur choix de type retour sur des types de béton afin que les implémentations puissent rester flexibles.


S'il est connu que la mise en œuvre ne changera jamais et que le type de retour sera toujours statique, puis le type de retour lui-même, dans la plupart des cas, serait le meilleur choix.