ICollection<T>.Contains 自定义类型

Posted

技术标签:

【中文标题】ICollection<T>.Contains 自定义类型【英文标题】:ICollection<T>.Contains on custom types 【发布时间】:2011-01-09 18:31:04 【问题描述】:

如果我有一个(参考 - 这有关系吗?)类型 MyType 不覆盖 Equals 方法,那么在确定 ICollection 包含该类型的给定实例?

使用我自己的启发式方法的最佳方法是什么(例如检查 Id 属性值的相等性)?

【问题讨论】:

您使用的是什么特定的集合? System.Collections.ObjectModel.Collection 【参考方案1】:

根据 MSDN:

实现方式可能会有所不同 确定对象的相等性;为了 例如, List)>) 使用 比较器)>)..::.Default, 而 Dictionary)>) 允许用户指定 IComparer)>) 用于比较的实现 键。

最好的方法是自己做这件事是使用带有IEqualityComparer&lt;T&gt;的重载

public class MyComparer : IEqualityComparer<MyType>

    public bool Equals(MyType x, MyType y)
    
        return x.Id == y.Id;
    

    public int GetHashCode(MyType obj)
    
        return obj.Id.GetHashCode();
    

【讨论】:

【参考方案2】:

AFAIK,将比较引用(内存中的地址)...

如果参考对您来说不够好,那么您可以比较 ID,正如您所提到的。

【讨论】:

【参考方案3】:

ICollection&lt;T&gt; 没有定义它——不同的实现可以使用不同的方法。来自MSDN:

实现方式可能会有所不同 确定对象的相等性;为了 例如,List&lt;T&gt; 使用 Comparer&lt;T&gt;.Default, 而Dictionary<TKey, TValue> 允许用户指定 IComparer&lt;T&gt; 用于比较的实现 键

在大多数情况下,它只会比较参考,但您应该查看文档以了解您正在使用的特定 ICollection&lt;T&gt;

【讨论】:

【参考方案4】:

因为您的类型没有覆盖 Equals,所以将使用 Equals 的默认实现,即引用相等。因此,如果集合包含 那个实例,那么 Contains 将为真。

要使用您自己的比较,请实现 IEqualityComparer&lt;T&gt;(例如比较 Id)并将您的比较器实例传递给 Contains 方法。 (这假设您能够使用 LINQ 扩展,因为“本机”ICollection&lt;T&gt;.Contains 方法没有 IEqualityComparer 重载。)

【讨论】:

不感兴趣的是值类型被平等对待,为什么不简单地覆盖 equals 方法? 如果所有字段都相等,则认为值类型相等。当然,您可以像在引用类型上一样覆盖值类型上的 Equals,并且可以像在引用类型上一样为值类型编写自定义 IEqualityComparer。

以上是关于ICollection<T>.Contains 自定义类型的主要内容,如果未能解决你的问题,请参考以下文章

ICollection<T>.Contains 自定义类型

IEnumerable,ICollection,IList接口问题

C# List<T;用法

c#中LIST的应用实例谁给个加注释的!灰常感谢!

哪个标准范围适用于C#8中的数组和字符串?

将通用字典<> 转换为 ICollection<> 问题