如何创建一个动态的平等的实现,你可以在属性名传递给被比较? [英] How do you create a dynamic equality implementation where you can pass in the property names to be compared?
问题描述
说我有下面的属性的对象的人:
Say I have an object Person with the properties below:
public class Person
{
public int ID { get; set; }
public int EmployeeNo { get; set; }
public string JobDescription { get; set; }
public string Code { get; set; }
}
我将如何动态检查特定属性的名字平等?
How would I dynamically check the equality of specific properties by name?
如:
var dynamicEqualityComparer = RetrieveDynamicEqualityComparer("ID", "JobDescription");
var intersectedPersons = listOfPerson1.Intersect(listOfPerson2, dynamicEqualityComparer);
上面的这段将使用默认LINQ交叉使用动态生成的相等比较法方法,只比较域ID和JobDescription。
The above snippit would use the default linq intersect method using the dynamically generated equality comparison method which only compares the fields "ID" and "JobDescription".
我会假设,这样的事情本来是很容易找到,但至今尚未能找到的任何东西。排序
I would assume that something like this would have been easy to find, but so far have not been able to locate anything of the sort.
推荐答案
我来解决的方法是如下:
The solution I came to is below:
平等的比较器类是这样的:
The equality comparer class looks like:
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());
}
}
要创建这个类,你的列表通过。代表对象的属性名称的字符串
To create this class, you pass in a list of strings representing the objects property names.
要调用这个类,我用下面的代码位:
To call this class, I used the following bit of code:
var groupKey = new List<string> {"EmployeeNo", "ID"}.ToArray();
var customEqualityComparer = new CustomPropertyEqualityComparer<object>(groupKey);
这与属性为employeeno和ID的类创建一个自定义相等比较。
This creates a custom equality comparer for any class with the properties "EmployeeNo" and "ID".
我检查时,如果两个表包含相同的条目,其中平等并不一定意味着每个字段等于..
I used this comparer when checking if two tables contain the same entries where equality doesn't necessarily mean that every single field is equal..
var existInBothTables = table1.Intersect(table2, customEqualityComparer).ToList();
这篇关于如何创建一个动态的平等的实现,你可以在属性名传递给被比较?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!