2

假设我有一个具有以下属性的对象 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 intersect 方法,使用动态生成的相等比较方法,该方法仅比较字段“ID”和“JobDescription”。

我会假设这样的东西很容易找到,但到目前为止还没有找到任何类似的东西。

4

2 回答 2

1

我得到的解决方案如下:

相等比较器类如下所示:

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”和“ID”属性的任何类创建一个自定义相等比较器。

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

var existInBothTables = table1.Intersect(table2, customEqualityComparer).ToList();
于 2013-06-10T03:26:01.083 回答
1

把它放在你的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 的覆盖,在覆盖等于您只需利用您自己的 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<> 接口的实现

于 2013-06-10T00:59:50.403 回答