1

首先,我会说我想比较以下内容:我的自定义对象(项目)有一个字符串列表taxids。我想查看一个列表中的所有字符串是否出现在另一个字符串列表中(也将是taxids另一个对象(项目)中的另一个。

所以,这是类:

public class Item
{
    public long taxid { get; set; }
    public long contentid { get; set; }
    public string taxname { get; set; }
    public IEnumerable<string> taxids { get; set; }
}

然后这些是虚拟的自定义对象:

    List<string> numbers = new List<string> { "5", "1" };
    List<string> numbers2 = new List<string> { "1", "2", "5","3","564" };

    Item pr = new Item();
    pr.contentid = 2517;
    pr.taxid = 2246;
    pr.taxids = numbers.AsEnumerable();
    pr.taxname = "nameItem1";
    List<Item> te = new List<Item>();
    te.Add(pr);
    IQueryable<Item> er = te.AsQueryable();

    Item pr2 = new Item();
    pr2.contentid = 0;
    pr2.taxid = 0;
    pr2.taxids = numbers2.AsEnumerable();
    pr2.taxname = "nameItem2";
    List<Item> te2 = new List<Item>();
    te2.Add(pr2);
    IQueryable<Item> er2 = te2.AsQueryable();

    IQueryable<Item> both = er.Intersect(er2, new ItemComparer());

在这里,我使用自定义比较器ItemComparer。这是此的代码:

public class ItemComparer : IEqualityComparer<Item>
{
    // items are equal if their names and item numbers are equal.
    public bool Equals(Item x, Item y)
    {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the items' properties are equal.
        return x.taxids.Intersect(y.taxids).SequenceEqual(x.taxids);
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.
    public int GetHashCode(Item item)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(item, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashItemName = item.taxids == null ? 0 : item.taxids.GetHashCode();

        //Calculate the hash code for the item.
        return item.taxids.GetHashCode();

        //return "a".GetHashCode();
    }
}

问题是该变量both在taxids 字段中没有任何内容,通常我应该有一个“5”“1”的列表。

我知道比较时 hashCode 必须相同。但taxids永远不会一样。因为我们在另一个字符串列表中查找字符串。

有人可以进一步帮助我解决这个问题吗?

(还有一个小问题:如果我总是为"a".GetHashCode()=> 之类的所有内容返回相同的哈希码,这是否可行?

提前致谢

4

2 回答 2

2

我认为您的问题是您没有双向平等。根据您的对象在哪一侧,pr 和 pr 2 不相等。

我不确定在您的比较器中是否可以保证哪个对象是 x,哪个是 y。如果pr2最终x进入您的比较器怎么办?

关于哈希码,你正在做taxids.GetHashCode()- 这只是一个列表而不是一个名字,不会告诉你任何关于平等的事情。

于 2011-12-19T09:58:15.387 回答
0
return x.taxids.Intersect(y.taxids).SequenceEqual(x.taxids);

您的相等比较当前不考虑集合中元素的不同顺序。作为一种粗略的解决方法,您可以在比较之前订购它们,或者更好地将项目添加到哈希集中:

return x.taxids.Intersect(y.taxids)
               .OrderBy(x => x)
               .SequenceEqual(x.taxids.OrderBy(x => x));

此外,您必须提供适当的实现GetHashCode(),默认实现不依赖于列表中的实际项目,因此不会为Item集合中具有相同元素的两个不同实例产生相同的哈希码。可以在此其他 SO 帖子中找到更适合您的案例的实现。

于 2011-12-19T09:55:23.980 回答