如果我正在使用ForEach中的引用,我试图理解.Except
和.ForEach
的连接如何在LINQ表达式中起作用。
我有一个IEnumaerable对象集合,我的要求是更新原始集合中对象子集的属性。我尝试在表达式中使用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();
}
}
输出:
{
{
"Bytes": 56,
"Name": "low",
"Code": "XS"
},
{
"Bytes": 123,
"Name": "medium",
"Code": null
},
{
"Bytes": 8888,
"Name": "large",
"Code": "M"
}
}
但是当我将.Aoray()连接到表达式的其余部分时,&#39; Code&#39;财产未更新
collection1.ToArray().Except(collection2, new CustomComparer()).ForEach(x=> x.Code= null);
return collection1;
输出:
{
{
"Bytes": 56,
"Name": "low",
"Code": "XS"
},
{
"Bytes": 123,
"Name": "medium",
"Code": "M"
},
{
"Bytes": 8888,
"Name": "large",
"Code": "M"
}
}
有人可以解释这两个表达式之间的区别是什么吗?
答案 0 :(得分:0)
如果您的Size
类覆盖Equals()
,则可以使用Except<T>()
方法而不使用IEqualityComparator。要使用您使用的Except<>(second, comparor)
方法,需要您构建自己的自定义比较器类。
选项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);
选项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;
}
}
在您的方法中:
collection1.Except(collection2, new MyComparator()).ForEach(x => x.Code = null);
答案 1 :(得分:-1)
调用chart.Series.Clear();
chart.Series[0].Items.Add(new DataPoint(1, 2));
会创建一个包含linq查询结果的新数组。因此,它实际上是创建了可枚举结果的副本(请在此处查看deferred execution的解释)。在第一个示例中,您将新创建的数组分配到ToArray()
变量中,然后在新数组上调用collection1
和Except
。在第二个示例中,您正在创建新数组并在其上调用Foreach
和Except
方法,但您没有在变量中捕获数组。相反,你将返回原始的可枚举。
查看此链接以获取更多信息:https://msdn.microsoft.com/en-us/library/bb298736(v=vs.100).aspx