gpt4 book ai didi

c# - 有人可以向我解释 LINQ 的相交吗?我不明白为什么这不起作用

转载 作者:太空狗 更新时间:2023-10-29 22:51:53 25 4
gpt4 key购买 nike

我有一个名为 Page 的对象和一个名为 p 的实例,该实例具有一个名为 AssociatedAttributes 的自定义属性。如果我执行以下操作:

int numMatchingAttributes = p.AssociatedAttributes.Intersect( p.AssociatedAttributes ).Distinct( ).Count( ); 

numMatchingAttributes 最终等于 0,即使 p 有 6 个 AssociatedAttributes。为什么不等于 6?

AssociatedAttributes类型为 List<Attribute> ( Attribute 是我自己的类(class),不是 System.Attribute )和 Attribute工具 IComparable<Attribute> ,我没有实现 IEquatable ,我应该吗?

这是 CompareTo 的实现在属性中:

public int CompareTo(Attribute other)
{
return Id.CompareTo(other.Id);
}

Id类型为 Guid .

这是 Page 上的 AssociatedAttributes 属性:

public List<Attribute> AssociatedAttributes
{
get
{
List<Attribute> list = new List<Attribute>( );
using (
PredictiveRecommendor dbContext =
new PredictiveRecommendor()){
if ( dbContext != null )
{
IQueryable<Attribute> query = from a in dbContext.PageAttributes
where a.Page.Id.Equals(this.Id)
select a.Attribute;
list = query.ToList();


}
}
return list;
}
}

(dbContext 是一个 Telerik OpenAccess 上下文)

更新:这是最终起作用的:在 Page 中是以下方法:

public int numberOfIntersectedAssociatedAttributes ( Page other )
{
using ( PredictiveRecommendor dbContext = new PredictiveRecommendor( ) )
{
IQueryable<Attribute> thisAssocAttributes = from a in dbContext.PageAttributes
where a.Page.Id.Equals( this.Id )
select a.Attribute;
IQueryable<Attribute> otherAssocAttributes = from a in dbContext.PageAttributes
where a.Page.Id.Equals( other.Id )
select a.Attribute;
IQueryable<Attribute> interSection = thisAssocAttributes.Intersect( otherAssocAttributes );

return interSection.ToList( ).Count;
}
}

它很丑,但它有效。

最佳答案

考虑以下 Page 的实现:

public class Page
{
public List<Attribute> AssociatedAttributes
{
get
{
return new List<Attribute>() {
new Attribute { Value = "a" },
new Attribute { Value = "b" },
new Attribute { Value = "c" },
};
}
}
}

这里是 AssociatedAttributes属性每次都返回不同的列表 AssociatedAttributes叫做。此外,列表中的实际项目是在每次调用该属性时构建的,它不仅仅是返回对完全相同的 Attribute 的引用。对象。自 Attribute (我假设)不会覆盖 EqualsGetHashCode , 它将使用默认的 object实现,当且仅当它们引用相同的对象时才认为对象相等。由于您的两个列表中的对象没有引用相同的对象,因此它们彼此都不相等,即使它们在内部可能具有相同的值。

事实Attribute工具 IComparable是无关紧要的。

有几种可能的方法可以改变行为:

  1. 与其在属性 getter 中构造新对象,不如返回对相同实际对象的引用。这可能意味着为该属性提供一个私有(private)支持字段,构造一次对象,然后返回对同一列表的引用。

  2. 覆盖 EqualsGetHashCodeAttribute依赖于它的值,而不是它的引用。惯例会规定只有在对象不可变时才这样做,就像处理具有变异的对象一样 GetHashCode值(value)观是……困难的。你可以实现 IEquatable 除此之外,如果您愿意,还可以提供静态类型的 Equals方法。请注意,覆盖 GetHashCode至关重要的如果你实现IEquatable ,如果您仍然希望它有用的话。

  3. 创建一个实现 IEqualityComparer<Attribute> 的新对象.这将是 Attribute 外部的对象知道如何根据 Equals 以外的东西比较它们是否相等和 GetHashCode对象本身的实现。将这种类型的实例提供给 IntersectDistinct . (它们每个都有自定义相等比较器的重载。)

关于c# - 有人可以向我解释 LINQ 的相交吗?我不明白为什么这不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18365587/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com