C# 通用平等检查器
我正在维护一个代码库,我发现了两个扩展方法,用于检查对象的结构相等性,我一点也不喜欢(一个调用另一个):C# 通用平等检查器,c#,equality,C#,Equality,我正在维护一个代码库,我发现了两个扩展方法,用于检查对象的结构相等性,我一点也不喜欢(一个调用另一个): public static bool IsObjectEqual(此T obj,T obj2) { foreach(obj.GetType().GetProperties()中的var pi) { var enumerable1=pi.GetValue(obj,null)作为IEnumerable; var enumerable2=pi.GetValue(obj2,null)作为IEnume
public static bool IsObjectEqual(此T obj,T obj2)
{
foreach(obj.GetType().GetProperties()中的var pi)
{
var enumerable1=pi.GetValue(obj,null)作为IEnumerable;
var enumerable2=pi.GetValue(obj2,null)作为IEnumerable;
如果(enumerable1!=null)
{
foreach(enumerable1中的变量项)
{
如果(enumerable2==null | |!((对象[])enumerable2).Contains(项))
{
返回false;
}
}
}
如果(!IsPropertyInfoValueEqual(pi、obj、obj2))为else,则为
{
返回false;
}
}
返回true;
}
私有静态布尔值IsPropertyInfoValueEqual(PropertyInfo pi、T obj、T obj2)
{
var val=pi.GetValue(obj,null);
var val2=pi.GetValue(obj2,null);
if(val!=null&&val2!=null)
{
返回val.Equals(val2);
}
返回值(val==null&&val2==null);
}
问题是,我很难想出一个我认为他们会失败或导致问题的方案。我深知他们错了,我就是不能指指点点
在实现平等性检查时,我总是使用iequatable
,因此没有任何处理平等性的框架类/接口是我的spidey感觉的一个原因。我意识到这种方法试图成为一种普遍的、基于反思的方法,但它让我感到紧张(如上所述)
有人能看出这些方法存在合法问题吗
编辑
这些方法存在很大的合法性问题。对对象[]的强制转换会导致InvalidCastException。可能还有其他异常,但我发现此代码存在两个主要问题:
IEnumerable
,则代码将无法按预期工作。其他所有内容都与反射进行比较,但是使用Contains
对集合进行比较。这将实现简单的引用相等(至少对于引用类型),并且不会重用反射方法。这可能会导致此方法的用户产生不希望的结果实施
IEquatable
和friends是一种更快、更安全的方法。实现者可以明确地决定比较是如何工作的,您不需要任何反思。这感觉像是一个代码审查问题。是的,但根本没有人访问该网站。这并不意味着它应该发布在这里。@BradleyDotNET非常感谢Bradley。请随意发表您的评论作为回答。我不担心落选。只要人们帮助我。
public static bool IsObjectEqual<T>(this T obj, T obj2)
{
foreach (var pi in obj.GetType().GetProperties())
{
var enumerable1 = pi.GetValue(obj, null) as IEnumerable;
var enumerable2 = pi.GetValue(obj2, null) as IEnumerable;
if (enumerable1 != null)
{
foreach (var item in enumerable1)
{
if (enumerable2 == null || !((object[])enumerable2).Contains(item))
{
return false;
}
}
}
else if (!IsPropertyInfoValueEqual(pi, obj, obj2))
{
return false;
}
}
return true;
}
private static bool IsPropertyInfoValueEqual<T>(PropertyInfo pi, T obj, T obj2)
{
var val = pi.GetValue(obj, null);
var val2 = pi.GetValue(obj2, null);
if (val != null && val2 != null)
{
return val.Equals(val2);
}
return (val == null && val2 == null);
}