Liste ou BusinessObjectCollection?

Avant C # Generics, tout le monde coderait les collections pour leurs objects métier en créant une base de collection qui implémenterait IEnumerable.

C’EST À DIRE:

public class CollectionBase : IEnumerable 

et puis dériverait leurs collections d’object métier de cela.

 public class BusinessObjectCollection : CollectionBase 

Maintenant, avec la classe de liste générique, est-ce que quelqu’un l’utilise simplement à la place? J’ai trouvé que j’utilise un compromis des deux techniques:

 public class BusinessObjectCollection : List 

Je le fais parce que j’aime avoir des noms fortement typés au lieu de simplement laisser passer des listes.

Quelle est votre approche?

Je suis généralement dans le camp de l’utilisation directe d’une liste, à moins que, pour une raison quelconque, je doive encapsuler la structure de données et fournir un sous-ensemble limité de ses fonctionnalités. Cela est principalement dû au fait que si je n’ai pas besoin d’encapsulation, le faire est une perte de temps.

Cependant, avec la fonctionnalité d’initialisation de l’agrégat dans C # 3.0, il existe certaines nouvelles situations dans lesquelles je préconiserais l’utilisation de classes de collecte personnalisées.

Fondamentalement, C # 3.0 autorise toute classe qui implémente IEnumerable et possède une méthode Add pour utiliser la nouvelle syntaxe d’initialisation d’agrégat. Par exemple, puisque Dictionary définit une méthode Add (clé K, valeur V), il est possible d’initialiser un dictionnaire en utilisant cette syntaxe:

 var d = new Dictionary { {"hello", 0}, {"the answer to life the universe and everything is:", 42} }; 

Ce qui est génial avec cette fonctionnalité, c’est qu’elle fonctionne pour append des méthodes avec un nombre quelconque d’arguments. Par exemple, compte tenu de cette collection:

 class c1 : IEnumerable { void Add(int x1, int x2, int x3) { //... } //... } 

il serait possible de l’initialiser ainsi:

 var x = new c1 { {1,2,3}, {4,5,6} } 

Cela peut être très utile si vous devez créer des tables statiques d’objects complexes. Par exemple, si vous utilisiez simplement List et que vous souhaitiez créer une liste statique d’objects client, vous devez la créer de la manière suivante:

 var x = new List { new Customer("Scott Wisniewski", "555-555-5555", "Seattle", "WA"), new Customer("John Doe", "555-555-1234", "Los Angeles", "CA"), new Customer("Michael Scott", "555-555-8769", "Scranton PA"), new Customer("Ali G", "", "Staines", "UK") } 

Cependant, si vous utilisez une collection personnalisée, comme celle-ci:

 class CustomerList : List { public void Add(ssortingng name, ssortingng phoneNumber, ssortingng city, ssortingng stateOrCountry) { Add(new Customer(name, phoneNumber, city, stateOrCounter)); } } 

Vous pouvez ensuite initialiser la collection en utilisant cette syntaxe:

 var customers = new CustomerList { {"Scott Wisniewski", "555-555-5555", "Seattle", "WA"}, {"John Doe", "555-555-1234", "Los Angeles", "CA"}, {"Michael Scott", "555-555-8769", "Scranton PA"}, {"Ali G", "", "Staines", "UK"} } 

Cela a l’avantage d’être à la fois plus facile à taper et à lire car il n’est pas nécessaire de ressaisir le nom du type d’élément pour chaque élément. L’avantage peut être particulièrement fort si le type d’élément est long ou complexe.

Cela étant, cela n’est utile que si vous avez besoin de collections statiques de données définies dans votre application. Certains types d’applications, comme les compilateurs, les utilisent tout le temps. D’autres, comme les applications de firebase database classiques, ne le font pas parce qu’elles chargent toutes leurs données à partir d’une firebase database.

Mon conseil serait que si vous devez soit définir une collection d’objects statiques, soit encapsuler l’interface de collection, créez une classe de collection personnalisée. Sinon, je voudrais simplement utiliser List directement.

Il est recommandé de ne pas utiliser List dans l’API publique, mais d’utiliser Collection

Si vous en héritez, vous devriez bien vous en sortir.

Je préfère juste utiliser List . Le typer ajoute simplement un passe-partout inutile au code. List est un type spécifique, ce n’est pas n’importe quel object List , il est donc toujours fortement typé.

Plus important encore, en déclarant quelque chose List il est plus facile pour tous ceux qui lisent le code d’indiquer les types avec lesquels ils traitent. Ils n’ont pas besoin de chercher pour savoir ce qu’est un BusinessObjectCollection et se rappeler que c’est juste une liste. En typedefing, vous devrez exiger une convention (re) de dénomination cohérente que tout le monde doit suivre pour que cela ait un sens.

Utilisez le type List où vous devez déclarer une liste. Cependant, lorsque vous retournez une liste de BusinessObject , envisagez de renvoyer IEnumerable , IList ou ReadOnlyCollection – c’est-à-dire de renvoyer le contrat le plus faible possible satisfaisant le client.

Où vous voulez “append un code personnalisé” à une liste, codez les méthodes d’extension sur le type de liste. Encore une fois, attachez ces méthodes au contrat le plus faible possible, par exemple

 public static int SomeCount(this IEnumerable someList) 

Bien sûr, vous ne pouvez pas et ne devez pas append d’état avec les méthodes d’extension, donc si vous devez append une nouvelle propriété et un champ derrière, utilisez une sous-classe ou mieux, une classe wrapper pour le stocker.

J’ai fait deux allers-retours:

 public class BusinessObjectCollection : List {} 

ou des méthodes qui ne font que:

 public IEnumerable GetBusinessObjects(); 

Les avantages de la première approche sont que vous pouvez modifier le magasin de données sous-jacent sans avoir à vous soucier des signatures de méthode. Malheureusement, si vous héritez d’un type de collection qui supprime une méthode de l’implémentation précédente, vous devrez alors gérer ces situations dans tout votre code.

Vous devriez probablement éviter de créer votre propre collection à cette fin. Il est assez courant de vouloir changer le type de structure de données plusieurs fois lors des refactorings ou lors de l’ajout de nouvelles fonctionnalités. Avec votre approche, vous vous retrouveriez avec une classe distincte pour BusinessObjectList, BusinessObjectDictionary, BusinessObjectTree, etc.

Je ne vois aucune valeur dans la création de cette classe simplement parce que le nom de classe est plus lisible. Oui, la syntaxe entre crochets est assez moche, mais elle est standard en C ++, en C # et en Java, donc même si vous n’écrivez pas de code qui l’utilise, vous le rencontrerez tout le temps.

Je fais exactement la même chose que vous, Jonathan… vous héritez de List . Tu reçois le meilleur des deux mondes. Mais je ne le fais généralement que lorsqu’il y a une certaine valeur à append, comme l’ajout d’une méthode LoadAll() ou autre.

En général, je ne dérive que mes propres classes de collection si je dois “append de la valeur”. Comme si la collection elle-même devait comporter des propriétés de “métadonnées” avec elle.

Vous pouvez utiliser les deux. Pour la paresse – je veux dire la productivité – la liste est une classe très utile, elle est aussi «complète» et franchement pleine de membres YANGNI. Couplé à l’argument / recommandation judicieux mis en avant par l’ article MSDN déjà lié à l’exposition de List en tant que membre public, je préfère le “troisième” moyen:

Personnellement, j’utilise le motif de décorateur pour exposer uniquement ce dont j’ai besoin dans List, à savoir:

 public OrderItemCollection : IEnumerable { private readonly List _orderItems = new List(); void Add(OrderItem item) { _orderItems.Add(item) } //implement only the list members, which are required from your domain. //ie. sum items, calculate weight etc... private IEnumerator Enumerator() { return _orderItems.GetEnumerator(); } public IEnumerator GetEnumerator() { return Enumerator(); } } 

Plus loin, je résumerais probablement OrderItemCollection dans IOrderItemCollection pour que je puisse remplacer mon implémentation de IOrderItemCollection dans le futur (je préférerais peut-être utiliser un object énumérable différent tel que Collection ou plus encore pour utiliser une collection ou un ensemble de valeurs clés) .

J’utilise des listes génériques pour presque tous les scénarios. La seule fois où je considérerais utiliser une collection dérivée, c’est si j’ajoute des membres spécifiques à une collection. Cependant, l’avènement de LINQ a diminué la nécessité de cela même.

6 sur 1, une demi-douzaine d’autres

De toute façon c’est la même chose. Je le fais uniquement lorsque j’ai des raisons d’append du code personnalisé dans BusinessObjectCollection.

Sans les méthodes de chargement, retourner une liste me permet d’écrire plus de code dans une classe générique commune et de la faire fonctionner. Comme une méthode de chargement.

Comme quelqu’un d’autre l’a fait remarquer, il est recommandé de ne pas exposer List publiquement, et FxCop va le faire si vous le faites. Cela inclut l’inheritance de List comme dans:

 public MyTypeCollection : List 

Dans la plupart des cas, les API publiques exposeront IList (ou ICollection ou IEnumerable), le cas échéant.

Si vous souhaitez créer votre propre collection personnalisée, vous pouvez conserver FxCop quiet en héritant de Collection au lieu de List.

Si vous choisissez de créer votre propre classe de collection, vous devez extraire les types dans l’ espace de noms System.Collections.ObjectModel .

L’espace de noms définit les classes de base pour faciliter la création de collections personnalisées par les implémenteurs.

J’ai tendance à le faire avec ma propre collection si je veux protéger l’access à la liste actuelle. Lorsque vous écrivez des objects métier, il y a de fortes chances que vous ayez besoin d’un crochet pour savoir si votre object est ajouté / supprimé. En ce sens, je pense que BOCollection est une meilleure idée. De coz si ce n’est pas nécessaire, List est plus léger. Vous pouvez également vérifier en utilisant IList pour fournir une interface d’abstraction supplémentaire si vous avez besoin d’une sorte de proxy (par exemple, une fausse collection déclenche un chargement paresseux depuis la firebase database)

Mais … pourquoi ne pas considérer Castle ActiveRecord ou tout autre framework ORM mature? 🙂

Tout au plus, je vais tout simplement avec la méthode List, car elle me donne toutes les fonctionnalités dont j’ai besoin à 90% du temps, et lorsque quelque chose de «supplémentaire» est nécessaire, j’en hérite et coder ce bit supplémentaire. .

Je ferais ceci:

 using BusinessObjectCollection = List; 

Cela crée simplement un alias plutôt qu’un type complètement nouveau. Je préfère utiliser directement List car cela me laisse libre de changer la structure sous-jacente de la collection à un moment donné sans changer le code qui l’utilise (tant que je propose les mêmes propriétés et méthodes).

essayez ceci:

 System.Collections.ObjectModel.Collection 

il est inutile de mettre en œuvre une méthode de base comme CollectionBase do

Ceci est le chemin:

retourner les tableaux, accepter IEnumerable

=)