我有两个属于我自己班级的列表,我正在尝试将所有项目放在一个不在另一个中的项目中。
//List<CADataType> ConsoleDataList is a list of 1071 CADataTypes
//List<CADataType> ComDataList is a list of 2153 CADataTypes
//This list ends up containing 1144 items
List<CADataType> intersectLoose = (from console in ConsoleDataList
join com in ComDataList
on console.CompareField equals com.CompareField
select console).ToList();
//Therefore there are 1144 items that are in both lists
//This SHOULD result in 2153 - 1144 = 1009 items
List<CADataType> remove = ComDataList.Except(ConsoleDataList).ToList(); //<-- Problem is here
//Ends up containing 2153 items
CADataType实际上是一个抽象类,所有列表实际上都有CAPropertyData。这是CAPropertyData的Equals类:
public override bool Equals(CADataType obj)
{
if (!(obj is CAPropertyData))
return false;
CAPropertyData y = (CAPropertyData)obj;
if (this.PropertyAddress.ToString() == y.PropertyAddress.ToString()) //Breakpoint here
return true;
return false;
}
我在Equals中的最后一个if语句上放了一个断点,当我进入Except行时它正确地命中断点,我可以看到this.PropertyAddress.ToString()
等于y.PropertyAddress.ToString()
in在某些情况下,所以它找到了一些相同的对象,但它似乎并没有排除它们?
知道什么是错的吗?
编辑: intersectLoose
可以向您显示两个列表中都有匹配的CADataType。
CompareField是使用与Equals方法相同的属性定义的:
public override string CompareField => PropertyAddress.ToString();
答案 0 :(得分:0)
您好这段代码可以帮助您:
ComDataList = ComDataList.Intersect(ConsoleDataList).ToList();
或
intersectLoose = ComDataList.Intersect(ConsoleDataList).ToList();
答案 1 :(得分:0)
您是否已实施GetHashCode()
? Equals()
和GetHashCode()
应始终一起实施。
请注意,生成的哈希码在计算后不应更改(例如,它应基于对象的ID),否则您将在以后遇到问题。
例如,我经常使用这个基类:
public abstract class DataObjectBase
{
public virtual int ID { get; set; }
// true if the entity is not saved yet:
public virtual bool IsTransient { get { return ID <= 0; } }
// alternatively, if ID is string:
// public virtual string ID { get; set; }
// public virtual bool IsTransient { get { return string.IsNullOrEmpty(ID); } }
public override bool Equals(object obj)
{
var other = obj as DataObjectBase;
if (other == null)
return false;
else if (IsTransient ^ other.IsTransient)
return false;
else if (IsTransient && other.IsTransient)
return ReferenceEquals(this, other);
else if (this.GetType() != other.GetType())
return false;
else return ID == other.ID;
}
private int? cachedHashCode; // this is used because hashcode shouldn't change
public override int GetHashCode()
{
if (cachedHashCode.HasValue) return cachedHashCode.Value;
cachedHashCode = IsTransient ? base.GetHashCode() : ID.GetHashCode();
return cachedHashCode.Value;
}
public static bool operator ==(DataObjectBase x, DataObjectBase y)
{
return Object.Equals(x, y);
}
public static bool operator !=(DataObjectBase x, DataObjectBase y)
{
return !(x == y);
}
}