cra*_*ay1 5 c# linq telerik-open-access
我有一个名为Page的对象,其中一个名为p的实例具有一个名为AssociatedAttributes的自定义属性.如果我执行以下操作:
int numMatchingAttributes = p.AssociatedAttributes.Intersect( p.AssociatedAttributes ).Distinct( ).Count( );
Run Code Online (Sandbox Code Playgroud)
numMatchingAttributes最终等于0,即使p有6个AssociatedAttributes.为什么它不等于6?
AssociatedAttributes是Type List<Attribute>(Attribute是我自己的类,不是System.Attribute)和Attribute实现IComparable<Attribute>,我没有它实现IEquatable,我应该吗?
这是CompareTo属性中的实现:
public int CompareTo(Attribute other)
{
return Id.CompareTo(other.Id);
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
(dbContext是Telerik OpenAccess上下文)
更新:以下是最终工作:在页面中是以下方法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这很难看,但它确实有效.
考虑以下实现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" },
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
AssociatedAttributes每次AssociatedAttributes调用时,属性都返回一个不同的列表.此外,每次调用属性时都会构造列表中的实际项目,而不仅仅是返回对相同精确Attribute对象的引用.由于Attribute(我假设)不会覆盖Equals或GetHashCode,它将使用默认object实现,当前和仅当它们引用同一对象时,它会将对象视为相等.由于两个列表中的对象不引用相同的对象,因此它们中的任何一个都不相等,即使它们在内部可能具有相同的值.
Attribute工具IComparable是不重要的事实.
可以通过以下几种方式来改变行为:
而不是在属性getter中构造新对象,而是返回对相同实际对象的引用.这可能意味着为属性创建一个私有支持字段,构造对象一次,然后将引用返回到同一列表.
倍率Equals和GetHashCode在Attribute依赖于它的值,而不是它的参考.惯例将规定如果对象是不可变的,你只会这样做,因为处理具有变异GetHashCode值的对象是困难的.IEquatable 除了这样做之外,如果需要,还可以实现提供静态类型的Equals方法.请注意,这是至关重要的覆盖GetHashCode,如果你实现IEquatable,如果你还希望它是有用的.
创建一个实现的新对象IEqualityComparer<Attribute>.这将是一个外部的对象,Attribute它知道如何基于除了对象本身Equals和GetHashCode实现之外的其他东西来比较它们.提供这种类型的一个实例Intersect和Distinct.(它们每个都有自定义相等比较器的重载.)
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |