如何创建动态相等实现,以便传入要进行比较的属性名称

本文关键字:比较 属性 创建 何创建 动态 实现 | 更新日期: 2023-09-27 18:17:32

假设我有一个Person对象,其属性如下:

    public class Person
    {
        public int ID { get; set; }
        public int EmployeeNo { get; set; }
        public string JobDescription { get; set; }
        public string Code { get; set; }
    }

如何根据名称动态检查特定属性的相等性?

var dynamicEqualityComparer = RetrieveDynamicEqualityComparer("ID", "JobDescription");
var intersectedPersons = listOfPerson1.Intersect(listOfPerson2, dynamicEqualityComparer);

上面的代码片段将使用默认的linq相交方法,使用动态生成的相等比较方法,该方法只比较字段"ID"answers"JobDescription"。

我认为这样的东西应该很容易找到,但是到目前为止还没有找到任何类似的东西。

如何创建动态相等实现,以便传入要进行比较的属性名称

将其放入person类中然后在实例中调用equals

    public override bool Equals(object obj)
            {
                return obj.ToString() == this.ToString();
            }
           public override int GetHashCode()
           {
               return this.ToString().GetHashCode();
           }
            public override string ToString()
            {
                string myState;
                myState = string.Format("[ID: {0};EmployeeNo : {1}; JobDescription: {2};Code :{3}]",ID,EmployeeNo,JobDescription,Code);
                return myState;
            }

因为tostring的重写包含了所有状态数据,所以在override中等于你只需利用您自己的ToString()实现。

public int Compare(Person x, Person y)
        {
            if (x.ID == y.ID && x.JobDescription == y.JobDescription) 
                return 0;
            return (x.ID > y.ID) ? 1 : -1;//here you put what condition to return here i put ID just
                                          //for clarity,if u want just return -1 for ex:
        } 

这是Person类型的IComparer<>接口的实现

我得出的解决方案如下:

相等比较器类如下:

public class CustomPropertyEqualityComparer<T>: IEqualityComparer<T> where T : class
{
    private readonly string[] _selectedComparisonProperties;
    public CustomPropertyEqualityComparer(params string[] selectedComparisonProperties)
    {
        _selectedComparisonProperties = selectedComparisonProperties;
    }
    public bool Equals(T x, T y)
    {
        if (x != null && y != null && x.GetType() == y.GetType())
        {
            var type = x.GetType();
            var comparableProperties = new List<string>(_selectedComparisonProperties);
            var objectProperties = type.GetProperties();
            var relevantProperties = objectProperties.Where(propertyInfo => comparableProperties.Contains(propertyInfo.Name));
            foreach (var propertyInfo in relevantProperties)
            {
                var xPropertyValue = type.GetProperty(propertyInfo.Name).GetValue(x, null);
                var yPropertyValue = type.GetProperty(propertyInfo.Name).GetValue(y, null);
                if (xPropertyValue != yPropertyValue && (xPropertyValue == null || !xPropertyValue.Equals(yPropertyValue)))
                {
                    return false;
                }
            }
            return true;
        }
        return x == y;
    }
    public int GetHashCode(T obj)
    {
        var type = typeof(T);
        var objectProperties = type.GetProperties();
        return objectProperties.Sum(property => property.GetHashCode());
    }
}

要创建这个类,您需要传入一个表示对象属性名称的字符串列表。

为了调用这个类,我使用了以下代码:
var groupKey = new List<string> {"EmployeeNo", "ID"}.ToArray();
var customEqualityComparer = new CustomPropertyEqualityComparer<object>(groupKey);

这将为任何具有"EmployeeNo"answers"ID"属性的类创建一个自定义相等比较器。

我在检查两个表是否包含相同的条目时使用了这个比较器,其中相等并不一定意味着每个字段都相等。

var existInBothTables = table1.Intersect(table2, customEqualityComparer).ToList();