如何实现按一个或多个元素属性加快搜索速度的集合

本文关键字:集合 属性 搜索 速度 元素 一个 实现 何实现 | 更新日期: 2023-09-27 18:35:07

我会在 C# 中创建自定义集合,这将通过其元素类型的一个或几个给定属性提供快速搜索。例如,我有组件列表和组件类具有类型(内部 .NET 属性,但我可以快速找到例如 Light - 它派生自组件)和唯一的 HashTag(字符串 - 我自己的属性)。所以我会在我自己的集合类型上拥有类似 FindByType(...) 和 FindByHashTag(...) 方法的东西,但以更"通用"的方式。

我使用"泛型"一词,因为此自定义集合应该可以轻松扩展为其他属性。

可以在 C# 中执行此操作,如果是这样,如何?

如何实现按一个或多个元素属性加快搜索速度的集合

此示例代码演示如何完成此操作。请注意,这假定要编制索引的每个属性都是唯一的。在此示例中,每个员工的 EmployeeID 都是唯一的。为了处理非唯一情况,您需要修改代码以具有如下所示的内容:

Dictionary<string, Dictionary<int, List<T>>> intIndexes = new Dictionary<string, Dictionary<int, List<T>>>();

而不是:

Dictionary<string, Dictionary<int, T>> intIndexes = new Dictionary<string, Dictionary<int, T>>();

此外,您必须重新定义 getByPropertyValue,如下所示:

public List<T> getByPropertyValue(string propertyName, int propertyValue)

理想情况下,最好提供提示,表明该属性是否唯一。这不是一个完整的实现,但你应该了解如何使用反射来实现你想要的东西。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IndexerSampleCode
{
    class Program
    {
        static void Main(string[] args)
        {
            Indexer<Employee> indexer = new Indexer<Employee>();
            Employee e = new Employee();
            e.EmployeeID = 45;
            e.FirstName = "Tarik";
            e.LastName = "Hoshan";
            e.BirthDate = new DateTime(1965, 2, 18);
            indexer.add(e);
            var e2 = indexer.getByPropertyValue("EmployeeID", 45);
            Console.WriteLine(e2.FirstName);
            Console.ReadKey();
        }
    }
    class Indexer<T>
    {
        // Collection of dictionories that will be used to index properties of type int
        Dictionary<string, Dictionary<int, T>> intIndexes = new Dictionary<string, Dictionary<int, T>>();
        public Indexer() {
            System.Type indexerType = this.GetType().UnderlyingSystemType;
            System.Type elementType = indexerType.GetGenericArguments()[0];
            var members = elementType.GetProperties();
            // Loop through each property and create a Dictionary corresponding to it
            foreach (var member in members)
            {
                if (member.PropertyType == typeof(int))
                {
                    intIndexes.Add(member.Name, new Dictionary<int, T>());
                }
            }
        }
        public T getByPropertyValue(string propertyName, int propertyValue)
        {
            Dictionary<int, T> index = intIndexes[propertyName];
            return index[propertyValue];
        }
        public void add(T o) {
            var type = o.GetType();
            var members = type.GetProperties();
            foreach (var member in members)
            {
                if (member.PropertyType == typeof(int))
                {
                    var propertyName = member.Name;
                    Dictionary<int, T> index = intIndexes[propertyName];
                    int value = (int) o.GetType().GetProperty(propertyName).GetValue(o, null);
                    index.Add(value, o);
                }
            }
        }
    }
    // Sample test class
    class Employee
    {
        public DateTime BirthDate
        {
            set;
            get;
        }
        public string FirstName
        {
            set;
            get;
        }
        public string LastName
        {
            set;
            get;
        }
        public int EmployeeID {
            set;
            get;
        }
    }
}

如果我理解正确,您可以使用字典执行此操作,但使用自定义类作为键。在自定义类中,必须实现GetHashCodeEquals方法,在GetHashCode中,可以返回基于一个或多个属性标识自定义类的哈希。

相关文章: