我需要定义一个方法来比较同一类型的两个不同对象。对象的类型不是特定的。对象可能是DLL类型,因此我无法覆盖Equals
方法。我必须通过反思来做到这一点。如果对象的所有成员都是基本类型,则此代码有效。但是当对象具有非原始字段时,它不起作用。我怎么能通过反思来做到这一点?
public bool Equals(object obj1, object obj2)
{
List<FieldInfo> fieldInfos = obj1.GetType().GetFields().ToList();
return (fieldInfos.Select(fieldInfo => new {fieldInfo, type = fieldInfo.GetType()})
.Where(@t => @t.type.IsPrimitive || @t.type == typeof(string) || @t.type == typeof(Decimal))
.Select(@t => @t.fieldInfo)).All(fieldInfo => fieldInfo.GetValue(obj1).Equals(fieldInfo.GetValue(obj2)));
}
答案 0 :(得分:5)
我最近被告知这个lib将完全符合您的要求
答案 1 :(得分:0)
我希望实用程序功能比较任何2个对象。我想要涵盖的所有类型都是
所以我使用泛型和反射来做到这一点。我这样编码。
public static bool CompareObjects<T>(T expectInput, T actualInput)
{
// If T is primitive type.
if (typeof(T).IsPrimitive)
{
if (expectInput.Equals(actualInput))
{
return true;
}
return false;
}
if (expectInput is IEquatable<T>)
{
if (expectInput.Equals(actualInput))
{
return true;
}
return false;
}
if (expectInput is IComparable)
{
if (((IComparable)expectInput).CompareTo(actualInput) == 0)
{
return true;
}
return false;
}
// If T is implement IEnumerable.
if (expectInput is IEnumerable)
{
var expectEnumerator = ((IEnumerable)expectInput).GetEnumerator();
var actualEnumerator = ((IEnumerable)actualInput).GetEnumerator();
var canGetExpectMember = expectEnumerator.MoveNext();
var canGetActualMember = actualEnumerator.MoveNext();
while (canGetExpectMember && canGetActualMember && true)
{
var currentType = expectEnumerator.Current.GetType();
object isEqual = typeof(Utils).GetMethod("CompareObjects").MakeGenericMethod(currentType).Invoke(null, new object[] { expectEnumerator.Current, actualEnumerator.Current });
if ((bool)isEqual == false)
{
return false;
}
canGetExpectMember = expectEnumerator.MoveNext();
canGetActualMember = actualEnumerator.MoveNext();
}
if (canGetExpectMember != canGetActualMember)
{
return false;
}
return true;
}
// If T is class.
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var expectValue = typeof(T).GetProperty(property.Name).GetValue(expectInput);
var actualValue = typeof(T).GetProperty(property.Name).GetValue(actualInput);
if (expectValue == null || actualValue == null)
{
if (expectValue == null && actualValue == null)
{
continue;
}
return false;
}
object isEqual = typeof(Utils).GetMethod("CompareObjects").MakeGenericMethod(property.PropertyType).Invoke(null, new object[] { expectValue, actualValue });
if ((bool)isEqual == false)
{
return false;
}
}
return true;
}