从自定义集合中检索项目

我有以下课程

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

我需要创建一个自定义集合,由类People的对象组成,它允许我通过其idnameHash检索元素。 该集合必须能够使用foreach迭代其元素:

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

我怎么做? 如果你不能给出详细的答案,至少要给出一个简短的行动计划。 提前致谢!

如果您正在讨论大型集合,并且您希望基于整数Id或字符串NameHash字段进行更快的查找,同时仍然支持foreach (Foo f in fooCollection)模式,那么您可以滚动自己的包含一对字典的集合。 原油实施,未经过全面测试:

 class Person { public int Id { get; private set; } public string NameHash { get; private set; } public string Name { get; private set; } public Person(int id, string nameHash, string 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[string 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); } 

当然,如果你正在处理一个小型集合,你可以简单地使用List并使用LINQ或已经定义的Find方法。 如

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

是否有必须成为自定义集合的特定原因? 为什么不

 List PeopleCollection = new List(); 

您可以使用idnameHash检索元素,并且可以迭代PeopleCollection

 class PeopleList : List { } 

这就是它。 只需inheritanceList就可以了。

顺便说一句,您应该重新考虑您的命名约定。 对于代表一个人的class级来说,“人”并不是一个好名字。 将其命名为“Person”,并将列表命名为“People”。

你有两个选择:

  1. 从现有集合类型inheritance,如其他答案中所示。
  2. 实现System.Collections.IEnumerableSystem.Collections.Generic.IEnumerable接口,这也意味着编写自己的System.Collections.IEnumerator实现或System.Collections.Generic.IEnumerator