C#Linq与对象的一部分相交/除外

我环顾四周,在这里找不到任何帮助。 我有一节课:

class ThisClass { private string a {get; set;} private string b {get; set;} } 

我想使用Linq的Intersect和Except方法,即:

 private List foo = new List(); private List bar = new List(); 

然后我单独填写两个列表。 我想做,例如(我知道这不对,只是伪代码),如下:

 foo[a].Intersect(bar[a]); 

我该怎么办?

谢谢你的帮助 :)

也许

 // returns list of intersecting property 'a' values foo.Select(f => fa).Intersect(bar.Select(b => ba)); 

BTW财产应该是公开的。

如果你想要一个你想要交叉的单个属性的列表,那么所有其他漂亮的LINQ解决方案都可以正常工作。 但! 如果你想在整个类上相交,那么结果是List而不是List你必须编写自己的相等比较器。

 foo.Intersect(bar, new YourEqualityComparer()); 

Except相同。

 public class YourEqualityComparer: IEqualityComparer { #region IEqualityComparer Members public bool Equals(ThisClass x, ThisClass y) { //no null check here, you might want to do that, or correct that to compare just one part of your object return xa == ya && xb == yb; } public int GetHashCode(ThisClass obj) { unchecked { var hash = 17; //same here, if you only want to get a hashcode on a, remove the line with b hash = hash * 23 + obj.a.GetHashCode(); hash = hash * 23 + obj.b.GetHashCode(); return hash; } } #endregion } 

与交叉和比较相比,不确定速度,但如何:

 //Intersect var inter = foo.Where(f => bar.Any(b => ba == fa)); //Except - values of foo not in bar var except = foo.Where(f => !bar.Any(b => ba == fa)); 
 foo.Select(x=>xa).Intersect(bar.Select(x=>xa)) 

究竟是什么效果? 当你通过a的唯一值识别两个ThisClass实例时,是否要获取由类中所有a组成的字符串列表或ThisClass列表?

如果是前者,@ lazyberezovksy和@Tilak的两个答案应该有效。 如果是后者,则必须覆盖IEqualityComparerIEquatable以便Intersect知道是什么使得ThisClass两个实例等效:

  private class ThisClass : IEquatable { private string a; public bool Equals(ThisClass other) { return string.Equals(this.a, other.a); } } 

然后你可以打电话:

  var intersection = foo.Intersect(bar); 

我知道这是旧的,但你不能只重写类本身的Equals和GetHashCode吗?

 class ThisClass { public string a {get; set;} private string b {get; set;} public override bool Equals(object obj) { // If you only want to compare on a ThisClass that = (ThisClass)obj; return string.Equals(a, that.a/* optional: not case sensitive? */); } public override int GetHashCode() { return a.GetHashCode(); } } 

您应该创建IEqualityComparer。 您可以将IEqualityComparer传递给Intersect()方法。 这将帮助您更轻松地获取List(与bar相交)。

 var intersectionList = foo.Intersect(bar, new ThisClassEqualityComparer()).ToList(); class ThisClassEqualityComparer : IEqualityComparer { public bool Equals(ThisClass b1, ThisClass b2) { return b1.a == b2.a; } public int GetHashCode(Box bx) { // To ignore to compare hashcode, please consider this. // I would like to force Equals() to be called return 0; } }