Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ,但不删除匹配项_C#_Linq - Fatal编程技术网

C# LINQ,但不删除匹配项

C# LINQ,但不删除匹配项,c#,linq,C#,Linq,我有两个我自己的类的列表,我正试图把所有的项目都放在一个列表中,而不是另一个列表中 //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> inte

我有两个我自己的类的列表,我正试图把所有的项目都放在一个列表中,而不是另一个列表中

//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
我在Equals中的最后一个if语句上放置了一个断点,当我进入Except行时,它正确地命中了断点,我可以看到
this.PropertyAddress.ToString()
在某些情况下等于
y.PropertyAddress.ToString()
,所以它正在查找一些相等的对象,但似乎没有排除它们

知道怎么了吗

编辑:
显示两个列表中都有匹配的地籍类型。
定义CompareField并使用与Equals方法相同的属性:

public override string CompareField => PropertyAddress.ToString();

您好,此代码可能会帮助您:

ComDataList = ComDataList.Intersect(ConsoleDataList).ToList();


您是否实现了
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);
    }
}
公共抽象类DataObjectBase
{
公共虚拟整数ID{get;set;}
//如果实体尚未保存,则为true:

public virtual bool IsTransient{get{return ID在使用join时,您正在使用CompareField检查它们之间的公共属性。但是,使用except是在比较整个对象。如果具有相同公共字段的两个对象也没有所有公共属性,这将不起作用。最好使用此ComDataList.except(intersectLose).ToList();这可能有助于@SubashKharel在本例中,
CompareField
实际上与Equals-
public override字符串CompareField=>PropertyAddress.ToString()相同
-但这无关紧要,因为我在连接中使用了比较字段来表示
交叉松散
,而我在例外中没有实际使用比较字段。是的,您仅在连接对象列表时使用了PropertyAddress字段,但在使用Exception时比较了整个对象。使用
。Exception
使用对象的
等于
方法-请参见above在我的问题中。我的Equals方法只检查PropertyAddress字段。如果PropertyAddress字段匹配,则两个CAPropertyType被视为相等。我已经实现了IEquatable接口,它只需要Equals(并且根本不使用GetHashCode函数-我之前已经实现了它,并且在调试中没有遇到它)重写Equals(Object)的类型也必须重写GetHashCode;否则,哈希表可能无法正常工作。请参阅:
intersectLoose = ComDataList.Intersect(ConsoleDataList).ToList();
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);
    }
}