public static bool PropertiesEqual<T>(T self, T to, params string[] skip)
where T : class
{
if (self != null && to != null)
{
var selfType = self.GetType();
var skipList = new List<string>(skip);
foreach (PropertyInfo pi in selfType.GetProperties(BindingFlags.Public |
BindingFlags.Instance))
{
if (skipList.Contains(pi.Name)) continue;
var selfValue = selfType.GetProperty(pi.Name).GetValue(self, null);
var toValue = selfType.GetProperty(pi.Name).GetValue(to, null);
if (selfValue != toValue && (selfValue == null ||
!selfValue.Equals(toValue)))
{
return false;
}
}
return true;
}
return self == to;
}
我想用扩展方法扩展我的EF实体,该方法比较两个实例的原始(?)属性(数字,字符串,bool和非附加对象等属性)。
我想知道的是,是否可以将其作为扩展方法?或者我是否需要在POCO类中为我想要执行的每种EF类型instance1.PropertiesEqual(instance2)
定义此内容?
我想知道的第二件事是如何正确地仅针对我上面提到的数据类型,并跳过附加对象(连接表)。
答案 0 :(得分:2)
要回答您的第一个问题,只要该方法存在于静态类中,您就可以轻松地将其定义为扩展方法。
其次,如果检查Type.IsByRef
,您将只获得字符串和结构属性,两者都具有Object.Equals的默认实现。
此实现也会在执行(昂贵的)属性比较之前检查null和相等。
如果您想加快速度,可以使用动态方法进行比较。
public static bool PropertiesEqual<T>(this T self, T other, params string[] skip)
{
if (self == null) return other == null;
if (self.Equals(other)) return true;
var properties = from p in typeof(T).GetProperties()
where !skip.Contains(p.Name)
&& !p.PropertyType.IsByRef // take only structs and string
select p;
foreach (var p in properties)
{
var selfValue = p.GetValue(self);
var otherValue = p.GetValue(other);
if (!object.Equals(selfValue, otherValue))
return false;
}
return true;
}