我通过反射获取属性,我这样做是为了迭代列表。
private string HandleListProperty(object oldObject, object newObject, string difference, PropertyInfo prop)
{
var oldList = prop.GetValue(oldObject, null) as IList;
var newList = prop.GetValue(newObject, null) as IList;
if (prop.PropertyType == typeof(List<DataModel.ScheduleDetail>))
{
List<DataModel.ScheduleDetail> ScheduleDetailsOld = oldList as List<DataModel.ScheduleDetail>;
List<DataModel.ScheduleDetail> ScheduleDetailsNew = newList as List<DataModel.ScheduleDetail>;
var groupOldSchedules = ScheduleDetailsOld
.GroupBy(x => x.HomeHelpID)
.SelectMany(s => s.DistinctBy(d => d.HomeHelpID)
.Select(h => new { h.HomeHelpID, h.HomeHelpName }));
var groupNewSchedules = ScheduleDetailsNew
.GroupBy(x => x.HomeHelpID)
.SelectMany(s => s.DistinctBy(d => d.HomeHelpID)
.Select(h => new { h.HomeHelpID, h.HomeHelpName }));
var AddedHomeHelp = string.Join(",", groupNewSchedules
.Where(x => x.HomeHelpID != null && !groupOldSchedule
.Any(y => y.HomeHelpID == x.HomeHelpID))
.Select(x => "\"<strong>" + x.HomeHelpName + "\"</strong>"));
var RemovedHomeHelp = string.Join(",", groupOldSchedules
.Where(x => x.HomeHelpID != null && groupNewSchedules
.Any(y => y.HomeHelpID != x.HomeHelpID))
.Select(x => "\"<strong>"+x.HomeHelpName+"\"</strong>"));
difference += string.IsNullOrWhiteSpace(RemovedHomeHelp) ? string.Empty : "<strong>HomeHelp</strong> " + RemovedHomeHelp + " Removed<br/>";
difference += string.IsNullOrWhiteSpace(AddedHomeHelp) ? string.Empty : "<strong>HomeHelp</strong> " + AddedHomeHelp + "Added<br/>";
}
}
现在我正在制作它是通用的,因为会有不同类型的列表,我不想放置if条件这样我想写 用于处理任何类型列表的通用代码。
我想出了这样的方式:
private void HandleListProperty(object oldObject, object newObject, string difference, PropertyInfo prop)
{
var oldList = prop.GetValue(oldObject, null) as IList;
var newList = prop.GetValue(newObject, null) as IList;
var ListType = prop.PropertyType;
var MyListInstance = Activator.CreateInstance(ListType);
MyListInstance = oldList;
}
我能够获取MyListInstance
中的项目,但由于类型将在运行时出现,我没有得到如何编写linq查询来过滤它们,任何想法如何做。
答案 0 :(得分:1)
您想要比较列表。据我了解,你比较的2个列表总是属于同一类型,但有一次它可能是2个X列表,另一个时间可能是2个Y列表。
LINQ Except方法非常适用于此。默认情况下,它会比较项目是否与完全相同的引用但使用自定义比较器,它可以根据ID属性或您想要的任何其他内容进行比较。
您需要确定如何将2个项目视为相等,并创建一个实现IEqualityComparer<T>
的自定义比较器,如下所示。
public class CompareSchedules : IEqualityComparer<ScheduleDetail>
{
public bool Equals(ScheduleDetail x, ScheduleDetail y)
{
return x.HomeHelpID == y.HomeHelpID;
}
public int GetHashCode(ScheduleDetail obj)
{
return obj.HomeHelpID;
}
}
public static class SuperDuperListComparer
{
public class ListCompareResults<T>
{
public List<T> RemovedItems { get; set; }
public List<T> AddedItems { get; set; }
}
public static ListCompareResults<T> CompareLists<T>(IList<T> list1, IList<T> list2, IEqualityComparer<T> comparer)
{
var addedItems = list2.Except(list1, comparer).ToList();
var removedItems = list1.Except(list2, comparer).ToList();
return new ListCompareResults<T>
{
AddedItems = addedItems,
RemovedItems = removedItems
};
}
public static ListCompareResults<T> CompareLists<T>(IList<T> list1, IList<T> list2)
{
return CompareLists<T>(list1, list2, EqualityComparer<T>.Default);
}
}
这是一些示例代码。
[TestMethod]
public void TestListComparer()
{
var list1 = new List<ScheduleDetail> {
new ScheduleDetail { HomeHelpID = 1},
new ScheduleDetail { HomeHelpID = 3}
};
var list2 = new List<ScheduleDetail> {
new ScheduleDetail { HomeHelpID = 1},
new ScheduleDetail { HomeHelpID = 5}
};
var comparison = SuperDuperListComparer.CompareLists(list1, list2, new CompareSchedules());
}
public class ScheduleDetail
{
public int HomeHelpID { get; set; }
}