从自定义集合中检索项目
我有以下课程
public class People { public int id; public string nameHash; public string name; }
我需要创建一个自定义集合,由类People
的对象组成,它允许我通过其id
和nameHash
检索元素。 该集合必须能够使用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 ();
您可以使用id
和nameHash
检索元素,并且可以迭代PeopleCollection
class PeopleList : List { }
这就是它。 只需inheritanceList
就可以了。
顺便说一句,您应该重新考虑您的命名约定。 对于代表一个人的class级来说,“人”并不是一个好名字。 将其命名为“Person”,并将列表命名为“People”。
你有两个选择:
- 从现有集合类型inheritance,如其他答案中所示。
- 实现
System.Collections.IEnumerable
或System.Collections.Generic.IEnumerable
接口,这也意味着编写自己的System.Collections.IEnumerator
实现或System.Collections.Generic.IEnumerator