Pourquoi utiliser ICollection et non IEnumerable ou List sur plusieurs-plusieurs/Un-plusieurs relations?
Je vois cela beaucoup dans les tutoriels, avec des propriétés de navigation comme ICollection<T>
.
Est-ce une exigence obligatoire pour Entity Framework? Puis-je utiliser IEnumerable
?
Quel est le but principal de l'utilisation de ICollection
au lieu de IEnumerable
ou encore List<T>
?
8 réponses
Habituellement, ce que vous choisissez dépendra des méthodes auxquelles vous devez accéder. En général - IEnumerable<>
(MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx) pour une liste d'objets qui ne doit être itérer, ICollection<>
(MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx) pour une liste des objets qui doivent être itérer et modifié, List<>
pour obtenir une liste des objets qui doivent être répétées à travers, modifié, triés, etc (Voir ici pour une liste complète: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).
D'un point de vue plus spécifique, le chargement paresseux vient jouer avec le choix du type. Par défaut, les propriétés de navigation dans Entity Framework sont fournies avec le suivi des modifications et sont des proxys. Pour que le proxy dynamique soit créé en tant que propriété de navigation, le type virtuel doit implémenter ICollection
.
Une propriété de navigation qui représente la fin" plusieurs " d'une relation doit renvoie un type qui implémente ICollection, où T est le type de l'objet à l'autre extrémité de la relation. - exigences pour la création de Proxies POCO MSDN
Plus d'informations sur la Définition et la Gestion des RelationsMSDN
ICollection<T>
est utilisé parce que l'interface IEnumerable<T>
ne fournit aucun moyen d'ajouter des éléments, de supprimer des éléments ou de modifier la collection.
Répondre à votre question sur List<T>
:
List<T>
est une classe; spécifier une interface permet plus de flexibilité d'implémentation. Une meilleure question est " pourquoi pas IList<T>
?"
Pour répondre à cette question, considérez ce que IList<T>
ajoute à ICollection<T>
: indexation entière, ce qui signifie que les éléments ont un ordre arbitraire, et peuvent être récupérés par référence à cet ordre. Cela n'a probablement pas de sens dans la plupart des cas, car les articles doivent probablement être classés différemment dans différents contextes.
Il y a quelques différences de base entre ICollection et IEnumerable
- IEnumerable - contient uniquement la méthode GetEnumerator pour obtenir un énumérateur et faire une boucle
- ICollection contient les méthodes suivantes - Ajouter/Supprimer/Contient/Compter/CopyTo
- ICollection est héritée de IEnumerable
- avec ICollection, vous pouvez modifier la collection en utilisant les méthodes comme add / remove, vous n'avez pas la liberté de faire la même chose avec IEnumerable.
Programme Simple:
using System;
using System.Collections;
using System.Collections.Generic;
namespace StackDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person("John",30));
persons.Add(new Person("Jack", 27));
ICollection<Person> personCollection = persons;
IEnumerable<Person> personEnumeration = persons;
//IEnumeration
//IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
foreach (Person p in personEnumeration)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
//ICollection
//ICollection Add/Remove/Contains/Count/CopyTo
//ICollection is inherited from IEnumerable
personCollection.Add(new Person("Tim", 10));
foreach (Person p in personCollection)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
Console.ReadLine();
}
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name,int age)
{
this.Name = name;
this.Age = age;
}
}
}
L'idée de base d'utiliser ICollection
est de fournir une interface pour un accès en lecture seule à une quantité finie de données. En fait, vous avez un ICollection.Le comte la propriété. IEnumerable
est plus approprié pour une chaîne de données où vous lisez jusqu'à un point logique, une condition esplicitly spécifiée par le consommateur ou jusqu'à la fin de l'énumération.
Je m'en souviens de cette façon:
IEnumerable a une méthode GetEnumerator() qui permet de lire les valeurs d'une collection mais pas d'y écrire. La plupart de la complexité de l'utilisation de l'énumérateur est prise en charge pour nous par le pour chaque instruction en C#. IEnumerable a une propriété: Current, qui renvoie l'élément current.
ICollection implémente IEnumerable et ajoute quelques propriétés supplémentaires dont le plus utilisé est Count. Le générique version de ICollection implémente les méthodes Add () et Remove ().
IList implémente à la fois IEnumerable et ICollection.
Ce que j'ai fait dans le passé est de déclarer mes collections de classes internes en utilisant IList<Class>
, ICollection<Class>
ou IEnumerable<Class>
(si liste statique) selon que je devrai ou non faire n'importe quel nombre de ce qui suit dans une méthode dans mon référentiel: enumerate, sort/order ou modify. Quand j'ai juste besoin d'énumérer (et peut-être de trier) sur des objets, je crée un temp List<Class>
pour travailler avec la collection dans une méthode IEnumerable. Je pense que cette pratique ne serait efficace que si la collecte est relativement faible, mais il peut être une bonne pratique en général, idk. Veuillez me corriger s'il existe des preuves indiquant pourquoi cela ne serait pas une bonne pratique.
Les propriétés de Navigation sont généralement définies comme étant virtuelles afin qu'elles puissent tirer parti de certaines fonctionnalités D'Entity Framework telles que le chargement paresseux.
Si une propriété de navigation peut contenir plusieurs entités (comme dans les relations plusieurs à plusieurs ou un à plusieurs), son type doit être une liste dans laquelle les entrées peuvent être ajoutées, supprimées et mises à jour, telles que ICollection.