C# 如何筛选列表<;T>;带LINQ和反射

C# 如何筛选列表<;T>;带LINQ和反射,c#,linq,list,generics,reflection,C#,Linq,List,Generics,Reflection,我通过反射获得属性,我这样做是为了在列表上迭代 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;

我通过反射获得属性,我这样做是为了在列表上迭代

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/>";
   }
}

我能够在MyListInstance中获取项目,但由于类型将在运行时出现,我不知道如何编写linq查询来过滤它们,也不知道如何进行过滤。

您想要比较列表。据我所知,您所比较的两个列表始终是同一类型的,但一次可能是两个X列表,另一次可能是两个Y列表

LINQ Except方法非常适合于此。默认情况下,如果项目是相同的精确引用,它将进行比较,但使用自定义比较器,它可以基于ID属性或任何其他您想要的内容进行比较

您需要确定如何考虑2个项目是相等的,并创建一个定制的比较器,实现如下代码< IEqualityComparer >代码>

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);
    }
}
公共类比较计划:IEqualityComparer
{
公共布尔等于(明细表x,明细表y)
{
返回x.HomeHelpID==y.HomeHelpID;
}
公共int GetHashCode(ScheduleDetail obj)
{
返回obj.HomeHelpID;
}
}
公共静态类SuperDuperListComparer
{
公共类ListCompareResults
{
公共列表RemovedItems{get;set;}
公共列表加法器{get;set;}
}
公共静态列表比较结果比较列表(IList列表1、IList列表2、IEqualityComparer比较程序)
{
var addedItems=list2.Except(list1,comparer.ToList();
var removedItems=list1.Except(list2,comparer.ToList();
返回新的ListCompareResults
{
AddedItems=AddedItems,
RemovedItems=RemovedItems
};
}
公共静态ListCompareResults比较列表(IList list1、IList list2)
{
返回比较列表(列表1、列表2、EqualityComparer.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; }

    }
[TestMethod]
公共void TestListComparer()
{
var list1=新列表{
新的ScheduleDetail{HomeHelpID=1},
新的ScheduleDetail{HomeHelpID=3}
};
var list2=新列表{
新的ScheduleDetail{HomeHelpID=1},
新的ScheduleDetail{HomeHelpID=5}
};
var comparison=SuperDuperListComparer.CompareLists(列表1,列表2,新的CompareSchedules());
}
公共类时间表详细信息
{
公共int HomeHelpID{get;set;}
}

请在设置代码格式方面投入更多精力-目前很难阅读,缩进到处都是。如果我正确理解您的问题,我将向此方法传递一个委托函数以执行筛选。你的具体实现似乎做了一些非通用的事情,所以你不能把它放在那里。@AndreasMüller没有明白你的意思,你能详细说明一下吗?第一个问题:我不认为你所有的列表都有
HomeHelpId
HomeHelpName
属性,是吗?如果没有,您还需要传递这些属性(属性名)。@RaphaëlAlthaus当然
DataModel.scheduledeail
有这些属性
    [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; }

    }