尝试确定两个List <t> </t>中的公共元素时出现问题

时间:2012-06-08 10:11:50

标签: c# .net linq

为了这个问题,我有一个名为ClassX的类,声明如下:

class X 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
}

如果我有instanceOne个这两个类的两个实例(instanceTwoList<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)

在这种情况下instanceTwoinstanceOne的超集,但情况可能并非总是如此,所以我应该能够翻转原始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;
}

2 个答案:

答案 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());
    }
}