首先,我将说明我要比较的内容:我的自定义对象(Item)有一个字符串列表taxids
。我想查看一个List中的所有字符串是否出现在另一个字符串列表中(也将是另一个Object(Item)的另一个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()
=&gt;这应该是否有效?
提前致谢
答案 0 :(得分:2)
我认为您的问题是您没有双向平等。取决于你的对象是哪一方,pr和pr 2不相等。
我不确定是否保证哪个对象是x,哪个是比较器中的y。如果pr2
在您的比较器中最终为x
,该怎么办?
关于哈希码,你正在做taxids.GetHashCode()
- 这只是一个列表,而不是一个名字,不会告诉你任何关于相等的信息。
答案 1 :(得分: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
实例生成相同的哈希码在集合中具有相同的元素。您可以在this other SO post中找到更合适的案例。