OK, j'espère que la communauté en général aidera à résoudre un débat sur le lieu de travail en cours depuis un certain temps. Cela concerne la définition d'interfaces acceptant ou renvoyer des listes de caractères. Il y a plusieurs façons de faire cela: ma propre préférence est d'utiliser iEnumerable pour les arguments et les tableaux pour les valeurs de retour: P> public interface Foo
{
void Do(IEnumerable<Bar> bars);
Bar[] Bars { get; }
}
8 Réponses :
Ma préférence est Un autre bon iMho, est ienumerable Readonlycollection
+1 Dans n'importe quelle application, j'ai travaillé sur, au moins, ienumerable code> est tout ce dont vous avez besoin de 98% du temps.
Ne pas dire que vous avez tort, mais cela ne suppose pas que vous ne réduisez pas une liste réadonnée ou une copie peu profonde (ou sans immuable)?
@annakata, mais comment exprimer cela à vos consommateurs? Vous ne pouvez pas simplement regarder un retour d'IList et savoir: 1) Devrais-je ne pas modifier cela, 2) est la modification désactivée en lancant (Dictionnaire
Ne copiez-vous toujours pas la liste
@Jared: Vous mettez un contractuel.ensures (contracter.Result
@Jon bonne idée. Mon plus gros problème avec les contrats est leur visibilité dans l'IDE (ils devraient être mieux mis en évidence). Encore une fois, je travaille sur une équipe IDE si ...
@Jarededpar: En effet. Bien sûr, si nous pouvions obtenir une vérification statique dans l'édition Visual Studio Non-Team-System, cela aiderait aussi ... :) Juste pour le garder pertinent: mon objection à Readonlycollection popsicleliste code> comme une autre collection en lecture seule (une mutable mais peut alors être "gelée" avant de le donner; un peu comme une chaîne). Ce serait bien de disposer d'une interface de ces types pourraient mettre en œuvre. (Certes popsiclelist n'est que immutaculable après la congélation, compliquant des choses ...)
@JOH, Kewl j'ai appris à apprendre quelque chose aujourd'hui ... j'avais totalement inconscient des contrats de code en 3.5. Je suppose que je reste laissé dans mon monde 2.0;)
@ csharpest.net je pense que les contrats de code sont le nouveau dans 4.0
Peut-être est peut-être iéalable pour les données qui sont par nature énumérées d'une manière paresseuse ... et réadonnycollection pour une liste pré-chargée, voir ma réponse à ce sujet.
@EGLASIUS: Non, utilisez simplement iEnumerable. Il n'y a plus de raison d'utiliser ReadOnlycollection (voir le commentaire de Jon ci-dessus, ainsi que sa réponse ici )
Je ne retourne pas de tableaux - ils sont vraiment un type de retour terrible à utiliser lors de la création d'une API - si vous avez vraiment besoin d'une séquence mutable, utilisez le aussi je suggérerais que vous lisiez Les tableaux considérés comme un peu nocifs par Eric Lippert: P>
J'ai une question morale d'un auteur
des manuels de langage de programmation le
autre jour demandant mes opinions sur
Si des programmeurs débutants ou non
devrait apprendre à utiliser des tableaux. P>
plutôt que de répondre à cela
question, je lui ai donné une longue liste de mon
Opinions sur les tableaux, comment j'utilise
tableaux, comment nous attendons des matrices pour être
utilisé dans le futur, et ainsi de suite. Cette
obtient un peu longtemps, mais comme Pascal, je
n'a pas eu le temps de le rendre plus court. p>
Permettez-moi de commencer par dire quand vous
ne devrait certainement pas utiliser des tableaux, et
puis cire plus philosophique sur le
avenir de la programmation moderne et de la
rôle de la matrice dans le monde à venir. P>
blockQuote> ilist ICollection < T> code> interface ou renvoyer une collection concrete
Pour les collections de propriétés indexées (et les indices ont une signification sémantique nécessaire), vous devez utiliser Les paramètres de la méthode doivent utiliser readonlycollection ilist ienumerable ICollection ienumerable icollection ilist comme ilist .tolist () code> quand cela échoue dans la mise en œuvre . p>
+1 Pour utiliser ce qui est approprié pour le scénario ... Ce n'est vraiment pas 1 à régner, alors tout ... Une autre façon de dire que ReadOnlyCollection vs. IEnumerable est pré-chargée contre paresseux chargé.
Je préférerais iEnumerable car il s'agit de la plus grande valise des interfaces donnant à l'utilisateur final la possibilité de redéfinir comme il le souhaite. Même si cela peut fournir à l'utilisateur une fonctionnalité minimale pour commencer (fondamentalement seulement l'énumération), il suffirait toujours de couvrir pratiquement tous les besoins, en particulier avec les méthodes d'extension, toarray (), tolis (), etc. p>
Je pense à cela en termes d'écriture du code le plus utile possible: code qui peut faire plus. p>
Mettez dans ces termes, cela signifie que j'aime accepter l'interface la plus faible em> possible comme arguments de méthode, car cela rend mon code utile à partir de plusieurs endroits. Dans ce cas, c'est un Cela signifie également que j'aime mes méthodes pour renvoyer l'interface la plus forte em> qui convient, de sorte que le code qui s'appuie sur la méthode peut facilement faire plus. Dans ce cas, ce serait Notez que je suis un peu non conventionnel en ce qui concerne les types de retour. Une approche plus typique consiste également à renvoyer également des types plus faibles des méthodes pour éviter de vous bloquer dans une implémentation spécifique. P> ienumerable ilist ilist
... si j'en ai déjà quelque chose qui implémente ilist
@ cshaparptest.net Si vous souagiez qu'un
Vous êtes correct ici; Mon croyance erronée était que ce serait évident que vous receviez une copie et qu'il ne serait pas de but de la modifier. J'admets que j'étais clairement faux là-bas par cette discussion ... elle ne m'a jamais eue que les gens feraient "foo.bars [0] = x" ou un tel bêtises. Quoi qu'il en soit, merci d'avoir aidé à m'éclairer +1 :)
IEnumerable Mais comme type de retour pour un niveau d'accès à des données typique, une propriété de compte est souvent utile et je préférerais renvoyer une icollection Il s'agit également d'une indication à l'appelant que la collection a été matérialisée. Et ainsi, l'appelant peut parcourir la collection renvoyée sans obtenir des exceptions à partir du niveau d'accès aux données. Cela peut être important. Par exemple, un service peut générer un flux (E.G. Savon) de la collection renvoyée. Il peut être gênant si une exception est lancée à partir de la couche d'accès aux données tout en générant le flux dû à une itération évaluée paresseuse, car le flux de sortie est déjà partiellement écrit lorsque l'exception est lancée. P>
Étant donné que les méthodes d'extension LINQ ont été ajoutées à IEnumerable
Je n'irais pas avec une matrice, c'est un type qui permet une modification encore n'a pas encore ajouté / enlever ... un peu comme le pire du peloton. Si je veux autoriser des modifications, j'utiliserais un type qui prend en charge Ajouter / Supprimer. P>
Lorsque vous souhaitez empêcher les modifications, vous l'emballez déjà / la copie, donc je ne vois donc pas ce qui ne va pas avec un iéalable ou une collection de lecture réveil. J'irais avec la plus tard ... quelque chose que je n'aime pas sur iEnumerable, c'est que c'est paresseux de la nature, mais lorsque vous utilisez des données préchargées uniquement pour l'envelopper, appelant le code qui fonctionne avec elle tend à supposer données chargées ou avoir des lignes "inutiles" supplémentaires :( ... qui peuvent obtenir des résultats laids pendant le changement. P>
J'ai vu les erreurs de mes manières. Autant d'Etat en dessous de ses développeurs, les développeurs évidents ne voient pas les propriétés [] comme immuables. Je suppose que mes abus d'eux m'ont appris de mauvaises habitudes. Je n'ai jamais vraiment soigné s'ils ont modifié la matrice puisqu'il s'agissait d'une copie; Cependant, je suis venu à réaliser la confusion qu'elle produit. IEnumerable est un gagnant de mains de mains que je pense.