Récupération d’éléments de la collection personnalisée

J’ai un cours suivant

public class People { public int id; public ssortingng nameHash; public ssortingng name; } 

J’ai besoin de créer une collection personnalisée, composée d’objects de la classe People , qui me permette de récupérer des éléments par leur id et nameHash . La collection doit avoir la capacité de parcourir ses éléments à l’aide de foreach:

 foreach (People person in PeopleCollection) { ... } 

Comment je fais ça? Si vous ne pouvez pas donner de réponse détaillée, donnez au moins un bref plan d’action. Merci d’avance!

Si vous parlez d’une grande collection et que vous souhaitez des recherches plus rapides basées sur un Id entier ou un champ NameHash chaîne tout en prenant foreach (Foo f in fooCollection) modèle foreach (Foo f in fooCollection) , vous pouvez foreach (Foo f in fooCollection) votre propre collection qui englobe une paire de dictionnaires. . Mise en œuvre brute, pas complètement testée

 class Person { public int Id { get; private set; } public ssortingng NameHash { get; private set; } public ssortingng Name { get; private set; } public Person(int id, ssortingng nameHash, ssortingng name) { Id = id; NameHash = nameHash; Name = name; } } class People : IEnumerable { private Dictionary personDictionary = new Dictionary(); private Dictionary hashIdMap = new Dictionary(); public void Add(Person person) { if (person == null) throw new ArgumentNullException("person"); if (personDictionary.ContainsKey(person.Id)) throw new InvalidOperationException("person Id is already referenced in collection."); if (hashIdMap.ContainsKey(person.NameHash)) throw new InvalidOperationException("person NameHash is already referenced in collection."); personDictionary.Add(person.Id, person); hashIdMap.Add(person.NameHash, person.Id); } public Person this[int id] { get { if (!personDictionary.ContainsKey(id)) throw new ArgumentOutOfRangeException("Id is not in the collection."); return personDictionary[id]; } } public Person this[ssortingng nameHash] { get { if (!hashIdMap.ContainsKey(nameHash)) throw new ArgumentOutOfRangeException("NameHash is not in the collection."); return this[hashIdMap[nameHash]]; } } public IEnumerator GetEnumerator() { foreach (KeyValuePair pair in personDictionary) yield return pair.Value; } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } 

 static void Main() { Person personA = new Person(1, "A", "Apple"); Person personB = new Person(2, "B", "Banana"); Person personC = new Person(3, "C", "Cherry"); People people = new People(); people.Add(personA); people.Add(personB); people.Add(personC); Person foo = people[1]; Person bar = people["C"]; Debug.Assert(foo.Name == "Apple"); Debug.Assert(bar.Name == "Cherry"); foreach (Person person in people) Debug.WriteLine(person.Name); } 

Bien sûr, si vous avez affaire à une collection de petite taille, vous pouvez très simplement utiliser un List et utiliser soit LINQ, soit les méthodes Find déjà définies. Tel que

 Person personA = collection.FirstOrDefault(p => p.Id == 42); Person personB = collection.Find(p => p.NameHash == "Blah"); 

Existe-t-il une raison spécifique pour laquelle il doit s’agir d’une collection personnalisée? Pourquoi pas

 List PeopleCollection = new List(); 

vous pouvez récupérer des éléments en utilisant id et nameHash et vous pouvez effectuer une itération sur PeopleCollection

 class PeopleList : List { } 

C’est à peu près tout. Héritez simplement de la List et vous êtes prêt.

BTW, vous devriez reconsidérer vos conventions de nommage. «People» n’est pas un bon nom pour une classe qui représente une seule personne. Nommez-le ‘Personne’ à la place et nommez votre liste ‘Personnes’.

Vous avez deux choix ici:

  1. Hériter d’un type de collection existant, comme indiqué dans d’autres réponses.
  2. Implémentez l’interface System.Collections.IEnumerable ou System.Collections.Generic.IEnumerable , ce qui signifie également l’écriture de votre propre implémentation de System.Collections.IEnumerator ou System.Collections.Generic.IEnumerator