0

我想在 C# 中制作自定义集合,这将通过其元素类型的一个或几个给定属性提供快速搜索。例如,我有组件列表,组件类有一个类型(内部 .NET 属性,但我希望快速找到 Light 的示例 - 它派生自 Component)和唯一的 HashTag(字符串 - 我自己的属性)。所以我想在我自己的集合类型上使用 FindByType(...) 和 FindByHashTag(...) 方法,但是以更“通用”的方式。

我使用“通用”这个词是因为这个自定义集合应该很容易扩展到其他属性。

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

4

2 回答 2

1

此示例代码说明了如何完成此操作。请注意,这假定要索引的每个属性都是唯一的。在此示例中,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;
        }
    }

}
于 2013-10-13T06:29:06.717 回答
1

如果我理解正确,您可以使用 Dictionary 但您的自定义类作为 Key。在自定义类中,您必须实现GetHashCodeEquals方法,并且GetHashCode您可以返回一个哈希,该哈希基于一个或多个属性来标识您的自定义类。

于 2013-10-12T11:17:20.667 回答