2024-05-11 13:34:39 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AioNet.Reflection
|
2024-05-11 12:48:50 +02:00
|
|
|
|
{
|
2024-05-11 13:34:39 +02:00
|
|
|
|
public static class DeepComparison
|
|
|
|
|
|
{
|
|
|
|
|
|
public static bool RecursiveFieldsEqual<T>(this T first, T second)
|
|
|
|
|
|
{
|
|
|
|
|
|
Type type = typeof(T);
|
|
|
|
|
|
return first.RecursiveFieldsEqual(second, type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static bool RecursiveFieldsEqual(this object first, object second, Type type)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If both are null, return true.
|
|
|
|
|
|
if (first is null && second is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If one of them is null and the other one isn't, return false.
|
|
|
|
|
|
if (first is null || second is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If type is value type or a String, simply return result of Equals.
|
|
|
|
|
|
if (type.IsValueType || type.Equals(typeof(string)))
|
|
|
|
|
|
{
|
|
|
|
|
|
return first.Equals(second);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If type is IEnumerable, compare individual elements.
|
|
|
|
|
|
if (type.GetInterface("System.Collections.IEnumerable") != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IEnumerable<FieldInfo> fields = type.GetRuntimeFields();
|
|
|
|
|
|
|
|
|
|
|
|
return fields.All(field =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return RecursiveFieldsEqual(
|
|
|
|
|
|
field.GetValue(first),
|
|
|
|
|
|
field.GetValue(second),
|
|
|
|
|
|
field.FieldType
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-05-11 12:48:50 +02:00
|
|
|
|
}
|