Retrieval of items from custom collection

后端 未结 4 962
失恋的感觉
失恋的感觉 2020-12-20 22:45

I have a following class

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

I need to create a

相关标签:
4条回答
  • 2020-12-20 23:02

    You have two choices here:

    1. Inherit from an existing collection type, as shown in other answers.
    2. Implement the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface, which also means writing your own implementation of System.Collections.IEnumerator or System.Collections.Generic.IEnumerator<T>
    0 讨论(0)
  • 2020-12-20 23:04

    If you're talking about a large collection and you want faster lookups based on an integer Id or a string NameHash field while still supporting the foreach (Foo f in fooCollection) pattern, then you can roll your own collection that wraps a pair of dictionaries. Crude implementation, not thoroughly tested:

    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<Person>
    {
        private Dictionary<int, Person> personDictionary = new Dictionary<int, Person>();
        private Dictionary<string, int> hashIdMap = new Dictionary<string, int>();
    
        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<Person> GetEnumerator()
        {
            foreach (KeyValuePair<int, Person> 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);
    }
    

    Of course, if you're dealing with a small-ish collection, you could very well simply use a List<T> and utilize either LINQ or the Find methods already defined. Such as

    Person personA = collection.FirstOrDefault(p => p.Id == 42);
    Person personB = collection.Find(p => p.NameHash == "Blah");
    
    0 讨论(0)
  • 2020-12-20 23:04

    Is there a specific reason why it has to be a custom collection? Why not

    List<People> PeopleCollection = new List<People>();
    

    you can retrieve elements using id and nameHash and you can iterate over PeopleCollection

    0 讨论(0)
  • 2020-12-20 23:26
    class PeopleList : List<People> {
    
    }
    

    That's pretty much it. Just inherit from List<T> and you're set.

    BTW, you should reconsider your naming conventions. 'People' is not a good name for a class that represents a single person. Name it 'Person' instead, and name your list 'People'.

    0 讨论(0)
提交回复
热议问题