我正在为简单通用比较器进行单元测试。
我不想使用IComparable接口,因为只有太多的类需要实现它,并且它只会在单元测试中使用,因此反射的性能不是问题。使用反射的通用比较器
到目前为止,我有这样的:
public IEnumerable<NonEqualProperty> Compare<T>(T first, T second) where T : class
{
var list = new List<NonEqualProperty>();
var type = first.GetType();
var properties = type.GetProperties();
var basicTypes = properties.Where(p => !p.PropertyType.IsClass && !p.PropertyType.IsInterface
|| p.PropertyType == typeof(string));
foreach (var prop in basicTypes)
{
var value1 = prop.GetValue(first, null);
var value2 = prop.GetValue(second, null);
if (value1 != null && value2 != null && value1.Equals(value2) || value1 == null && value2 == null)
continue;
list.Add(new NonEqualProperty(prop.Name, value1, value2));
}
var enumerableTypes =
from prop in properties
from interfaceType in prop.PropertyType.GetInterfaces()
where interfaceType.IsGenericType
let baseInterface = interfaceType.GetGenericTypeDefinition()
where prop.PropertyType != typeof(string) && baseInterface == typeof(IEnumerable<>) || baseInterface == typeof(IEnumerable)
select prop;
foreach (var prop in enumerableTypes)
{
var collection = prop.GetValue(first, null);
}
return list;
}
因此,所有简单类型+字符串作品的比较。
现在我想通过IEnumerable(它始终可以枚举一个类,尽管处理不好的情况很好),并使用递归比较值。像这样:
foreach (var prop in enumerableTypes)
{
var typeOfItemsInList= ...;
var collection1 = (IEnumerable<typeOfItemsInList>) prop.GetValue(first, null);
var collection2 = (IEnumerable<typeOfItemsInList>) prop.GetValue(second, null);
for (int i = 0; i < collection1.Count; i++)
{
var item1 = collection1[i];
var item2 = collection2[i];
Compare<typeOfItemsInList>(item1, item2, list);
}
}
我该如何实现这一目标?
不相等的数量或列表中的项目顺序在这里没有考虑 - 我会在稍后修复它。
虽然我没有时间看你的问题,我已经与之前这样的比较器工作,想补充一点:不要忘了空类型(例如int?),并且由于存储机制和舍入错误的不同,日期和浮点数等可能无法进行比较。他们会来,并在某些时候让你感到惊讶:) – john
问题是什么? –
为什么不使用NUnit等测试库?它提供了您正在寻找的功能,以及更多。 – mireigi