2

我有一个类,ClassX为了这个问题的目的而调用,声明如下:

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

如果我有这些类的两个实例(instanceOneinstanceTwo),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 语句(我试图确定共同元素)不起作用,谁能发现我做错了什么?

编辑 2012-06-08 11:00 UTC

根据@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;
}
4

2 回答 2

4

如果Except有效,那么

var commonItems = instanceOne.Intersect(instanceTwo);

也应该工作。:)

在旁注中,它会比较引用,所以如果你想要不同的功能,你必须实现你自己的IEqualityComparer- 但同样适用于Except.

于 2012-06-08T10:15:35.173 回答
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());
    }
}
于 2012-06-08T11:04:16.293 回答