2 回答
TA贡献1788条经验 获得超4个赞
我知道这可能有点晚了,但万一其他人有同样的问题......
当List<T>.Contains(...)
被调用时,它使用了EqualityComparer<T>.Default
比较个别项目发现你在[1]通过什么。该文件说,这一下EqualityComparer<T>.Default
:
Default 属性检查类型 T 是否实现了 System.IEquatable 接口,如果是,则返回使用该实现的 EqualityComparer。否则,它返回一个使用 T 提供的 Object.Equals 和 Object.GetHashCode 覆盖的 EqualityComparer。
由于您LRItem
没有不执行IEquatable<T>
的话,就回退到使用Object.Equals(object, object)
。因为LRItem
是一个结构,所以它最终会被装箱为一个,object
所以它可以被传递给Object.Equals(...)
,这是分配的来源。
解决此问题的简单方法是从文档中获取提示并实现IEquatable<T>
接口:
public struct LRItem : IEquatable<LRItem>{ // ... public bool Equals(LRItem other) { // Implement this return true; }}
现在这将导致EqualityComparer<T>.Default
返回一个不需要对LRItem
结构进行装箱的专用比较器,从而避免分配。
[1] 我不确定自从提出这个问题以来是否发生了一些变化(或者可能是 .net 框架与核心差异之类的东西),但现在List<T>.Contains()
没有调用Array.IndexOf()
。无论哪种方式,它们都遵循EqualityComparer<T>.Default
,这意味着这在任何一种情况下都应该是相关的。
TA贡献1807条经验 获得超9个赞
您的对象不是像 text 或 number 这样的简单数据类型,因此检查每个项目中的复杂对象可能是内存杀手。
例如,如果您的对象包含图像、文本、数字和......每个数据都应该进行相似性处理。
我建议您不要使用 IndexOf 或 Contains 函数,因为它们 可能会比较对象中的每一个数据。
只是做手工,用一个单一的foreach循环和只是比较你的关键数据(用户ID,对象ID,姓名,家庭,日期,时间或......)。
- 2 回答
- 0 关注
- 172 浏览
添加回答
举报