为了这个问题,我有一个名为ClassX
的类,声明如下:
class X
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
如果我有instanceOne
个这两个类的两个实例(instanceTwo
和List<T>
),我怎样才能找到两个实例中相同的元素:
假设instanceOne中有两个元素,instanceTwo中有四个元素。在每个实例中,其中两个元素是相同的(由它们具有相同的Guid Id的事实定义)
我以为我应该能够LINQ到达它,但这不是为我做的
// What's common to the two instances?
var commonElements = (
from a in instanceTwo
join b in instanceOne on a.Id equals b.Id
select b).ToList();
// What's not in instanceOne and in instanceTwo?
var notInInstanceOne = instanceTwo.Except(commonElements)
在这种情况下instanceTwo
是instanceOne
的超集,但情况可能并非总是如此,所以我应该能够翻转原始LINQ语句以获取instanceOne
中的元素不在instanceTwo
即:
var notInInstanceTwo = instanceOne.Except(commonElements)
令人沮丧的原始LINQ声明(我试图确定常见元素的地方)不起作用,有人能发现我做错了吗?
EDIT 2012-06-08 11:00 UTC
Per @Nikhil Agrawal和@Trust me - 我是医生我使用过Intersect方法,但这不会产生预期的结果:
var commonItems = instanceTwo.Intersect(instanceOne); // Returns nothing
var itemsInTwoNotOne= instanceTwo.Except(instanceOne); // Returns everything in instanceTwo
FWIW我对Equals()方法的实现是:
public bool Equals(Guid x, Guid y)
{
if (x == y)
{
return true;
}
return false;
}
答案 0 :(得分:4)
如果Except
有效,那么
var commonItems = instanceOne.Intersect(instanceTwo);
也应该有用。 :)
在旁注中,它会比较引用,因此如果您需要不同的功能,则必须实现自己的IEqualityComparer
- 但Except
也是如此。
答案 1 :(得分:1)
使用可以使用intersect获取所有常用元素的列表。您还应创建IEqualityComparer,因为您希望通过其ID来识别元素。
示例:
class Program
{
class X
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
class XequalityComparer : IEqualityComparer<X>
{
//Note: maybe add a null check in these methods
public bool Equals(X x, X y) { return x.Id.Equals(y.Id); }
public int GetHashCode(X obj) { return obj.Id.GetHashCode(); }
}
static void Main(string[] args)
{
var instanceOne = new List<X>() {
new X() { Id = Guid.NewGuid() },
new X() { Id = Guid.Parse("EF42EE32-1B9E-493C-9D39-4610E0FB29D0") }
};
var instanceTwo = new List<X>() {
new X() { Id = Guid.NewGuid() },
new X() { Id = Guid.Parse("EF42EE32-1B9E-493C-9D39-4610E0FB29D0") }
};
var common = instanceOne.Intersect(instanceTwo, new XequalityComparer());
}
}