2013-12-13 51 views
0

我有两个列表。第一个是所有学生,第二个是选定的学生。我希望如果我一次选择一些学生,他们将从全体学生名单中删除。这是我的代码,但它没有。学生不会被删除。从列表中移除项目时遇到困难?

foreach (var li in ListSelectedStudents.ToList()) 
{ 
    if (ListAllStudents.Contains(li)) 
    { 
     ListAllStudents.Remove(li); 
    } 
} 
+0

你得到一个错误? – scheien

+0

它不起作用? – Arran

+0

不,我没有得到任何错误,但学生不会从我的全部学生名单中删除 – Coderz

回答

2

你尝试使用LINQ:

ListAllStudents.RemoveAll(m => ListSelectedStudents.Contains(m)); 

,如果它不能正常工作,它可能是一些错误的对象实现的默认的比较,你既可以解决的比较器,或做是这样的:

ListAllStudents.RemoveAll(m => ListSelectedStudents.Any(n=>n.Id == m.Id)); // Assume the Id is the primary key of the object... 
+1

+1虽然linq实现中的相对性能会有所不同,但我无法让自己的头脑为非'IQUatatable'替代,但实现本身很好,简洁。 –

+0

修复后面的对象来实现IEquatable其实会更好 - 它将消除在需要比较的地方使用linq和谓词的需要......我想原始代码没有使用自定义对象,或者对象不是正确使用 - 在理论上,简单的对象不应该多次重复生成并存储在不同的集合中。 – Rex

4

Contains会用平等来确定什么是“平等”,我在这里假设你的自定义类并没有提供自定义平等的实现,这意味着将为该类型提供默认的equatable,并且仅使用引用相等。所以,即使您认为两件事情“相等”,Contains方法不会,因此也不会进入Remove调用。

要获得特定代码的行为,你需要做的是提供IEquatable<Student>Student类的实现,因为在备注here描述。

在这种情况下,Contains实际上并不需要,因为Remove将执行相同的检查。如果没有东西可以删除,则调用将是透明的,实际上什么也不做。

正如在评论中被抓之前,我有机会提供信息,Remove还将依托IEquatable<Student>docs),所以你仍然需要提供一个实现,但它会使你的代码看起来干净了一点:

foreach (var li in ListSelectedStudents.ToList()) 
{ 
    ListAllStudents.Remove(li); 
} 

可能有多种方法可以在不需要实现接口的情况下做到这一点,但是您将无法使用当前的代码。我会留下其他答案,在星期五发布这些替代方案,并且我的大脑还没有正常工作。

+0

我假设它是'ListItem',其中'Equals'被覆盖。但是两者都必须是'ListItem'类型,并且都必须具有相同的'Text' **和**'Value'。 –

+0

@TimSchmelter我不知道,这个问题中缺少很多支持信息。我刚刚读了“学生名单”,因此假定一个习惯课程在某处停留。如果它不是一个可以控制的自定义类,我的答案可能不再完全正确。 –

+1

是的,我也只是猜测,因为常见的缩写。没有人应该回答这些问题,直到OP没有澄清。 –

0

试试这个:

ListSelectedStudents = ListSelectedStudents.Where(a => !ListSelectedStudents.Contains(a)).Select(a => a).ToList();