C# LINQ-IEnumerable集合上的筛选和更新属性

C# LINQ-IEnumerable集合上的筛选和更新属性,c#,linq,C#,Linq,如果我在使用ForEach中的引用,我试图理解.Except和.ForEach的串联在LINQ表达式中是如何工作的 我有一个IEnumerable对象集合,我的要求是更新原始集合中对象子集的属性。我尝试在表达式中使用except和foreach,但属性没有更新 private Size[] FilterCollection() { var collection1 = { { "Bytes": 56, "Name": "low", "Code":

如果我在使用ForEach中的引用,我试图理解.Except和.ForEach的串联在LINQ表达式中是如何工作的

我有一个IEnumerable对象集合,我的要求是更新原始集合中对象子集的属性。我尝试在表达式中使用except和foreach,但属性没有更新

private Size[] FilterCollection()
{    
   var collection1 = { {
      "Bytes": 56,
      "Name": "low",
      "Code": "XS"
    },
    {
      "Bytes": 123,
      "Name": "medium",
      "Code": "M"
    },
    {
      "Bytes": 8888,
      "Name": "large",
      "Code": "M"
    }
  };

  var collection2 = { {
      "Bytes": 56,
      "Name": "low",
      "Code": "XS"
    },
    {
      "Bytes": 8888,
      "Name": "large",
      "Code": "M"
    }
  };                     

 collection1= collection1.ToArray();
 collection1.Except(collection2, new CustomComparer()).ForEach(x=> x.Code= null);
 return collection1;
}

 private class CustomComparer: IEqualityComparer<Size>
    {
        public bool Equals(Size x, Size y)
        {
            return x.Name == y.Name;
        }

        public int GetHashCode(Size obj)
        {
            return obj.Name.GetHashCode();
        }
    }
但是当我将.ToArray连接到表达式的其余部分时,“Code”属性不会更新

collection1.ToArray().Except(collection2, new CustomComparer()).ForEach(x=> x.Code= null);
return collection1;
输出:

{ 
    {
      "Bytes": 56,
      "Name": "low",
      "Code": "XS"
    },
    {
      "Bytes": 123,
      "Name": "medium",
      "Code": null
    },
    {
      "Bytes": 8888,
      "Name": "large",
      "Code": "M"
    }
}
{ 
    {
      "Bytes": 56,
      "Name": "low",
      "Code": "XS"
    },
    {
      "Bytes": 123,
      "Name": "medium",
      "Code": "M"
    },
    {
      "Bytes": 8888,
      "Name": "large",
      "Code": "M"
    }
}
有人能解释一下这两个表达式之间的区别吗?

调用ToArray将使用linq查询的结果创建一个新数组。因此,它本质上是创建一个可枚举结果的副本。请查看此处以了解有关的解释。在第一个示例中,将新创建的数组分配到collection1变量中,然后对新数组调用Except和Foreach。在第二个示例中,您正在创建新数组并对其调用Except和Foreach方法,但没有在变量中捕获数组。相反,您将返回原始的可枚举项

查看此链接以了解更多信息:

如果大小类覆盖等于,则可以在不使用IEqualityComparator的情况下使用Exceptmethod。要使用所使用的Exceptsecond、comparator方法,需要构建自己的自定义comparator类

备选案文1:

public class Size
{
    //Properties and stuff...

    public override Equals(object obj)
    {
        Size other = obj as Size;
        if (other != null)
            return other.Name == this.Name && other.Bytes == this.Bytes;
        return false;
    }
}
在您的方法中:

collection1.Except(collection2).ForEach(x => x.Code = null);
collection1.Except(collection2, new MyComparator()).ForEach(x => x.Code = null);
备选案文2:

public class MyComparator : IEqualityComparer<Size>
{
    public bool Equals(Size x, Size y)
    {
        return x.Name == y.Name && x.Bytes == y.Bytes;
    }

    public int GetHashCode(Size obj)
    {
        return obj.Bytes;
    }
}

复制CustomComparer类的代码。这应该会有帮助。这看起来不像是有效的C代码。你是想用一种特殊的方式来显示初始化和输出还是别的什么,因为你把我弄糊涂了。没错,调用ToArray会创建一个新的集合,但是使用相同的对象引用,提供的大小是一个类,而不是一个结构。因此,更改新数组中的属性将更改旧集合中的属性。