Jam*_*ing 6 c# linq iequatable iequalitycomparer gethashcode
泛型List<T>可以包含任何类型 - 值或引用。当检查列表是否包含对象时,.Contains()使用类型 T 的默认值EqualityComparer<T>并调用.Equals()(这是我的理解)。如果没有定义 EqualityComparer,则默认比较器将调用.Equals(). 默认情况下,.Equals()调用.ReferenceEquals(), so.Contains()仅当列表包含完全相同的对象时才返回 true。
直到您需要重写.Equals()以实现值相等,此时默认比较器表示如果两个对象具有相同的值,则它们是相同的。我想不出有哪一种情况适合引用类型。
我从 @Enigmativity 听到的是,实现IEqualityComparer<StagingDataRow>将为我键入的 DataRow 提供一个默认的相等比较器,该比较器将用于代替Object\xe2\x80\x93 的默认比较器,从而允许我在StagingDataRow.Equals().
问题:
\nEqualityComparer<StagingDataRow>.Equals()而不是调用StagingDataRow.Equals()?IEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)哈希什么,它应该返回与 相同的值吗StagingDataRow.GetHashCode()?IEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)?我正在寻找的对象还是列表中的对象?两个都?让实例方法接受自身作为参数会很奇怪......一般来说,在重写时如何区分值相等和引用相等.Equals()?
引发这个问题的原始代码行:
\n// For each ID, a collection of matching rows\nDictionary<string, List<StagingDataRow>> stagingTableDictionary;\n\n\nStagingTableMatches.AddRange(stagingTableDictionary[perNr].Where(row => !StagingTableMatches.Contains(row)));\n\n.\nRun Code Online (Sandbox Code Playgroud)\n 好吧,让我们先解决一些误解:
\n\n\n\n\n默认情况下,
\n.Equals()调用.ReferenceEquals(), so.Contains()仅当列表包含完全相同的对象时才返回 true。
这是正确的,但仅适用于引用类型。值类型将实现非常慢的基于反射的Equals函数,因此覆盖它最符合您的利益。
\n\n\n我想不出有哪一种情况适合引用类型。
\n
哦,我确信你可以...String例如是引用类型:)
\n\n\n我从 @Enigmativity 听到的是,实现
\nIEqualityComparer<StagingDataRow>将为我输入DataRow一个默认的相等比较器,该比较器将用于代替Object\xe2\x80\x93 的默认比较器,从而允许我在StagingDataRow.Equals().
呃……不。
\n\nIEqualityComaprer<T>是一个接口,可让您将相等比较委托给不同的对象。如果您希望您的类有不同的默认IEquatable<T>行为,您可以实现,并委托object.Equals给它以保持一致性。实际上,覆盖object.Equalsandobject.GetHashCode足以改变默认的相等比较行为,而且实现还有额外的好处:IEquatable<T>
object.Equals)因此,对于您的实际问题:
\n\n\n\n\n我的理解正确吗?
\n
您似乎对此仍然有点困惑,但不用担心:)
\n\nEnigmativity 实际上建议您创建一个实现IEqualityComparer<T>. 看来你误解了那部分。
\n\n\n我是否保证 .NET 框架中的所有内容都会调用
\nEqualityComparer<StagingDataRow>.Equals()而不是StagingDataRow.Equals()
默认情况下,(正确编写的)框架数据结构会将相等比较委托给EqualityComparer<StagingDataRow>.Default,而后者又会委托给StagingDataRow.Equals。
\n\n\n应该
\nIEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)哈希什么,它应该返回与以下内容相同的值StagingDataRow.GetHashCode()
不必要。它应该是自洽的:如果myEqualitycomaprer.Equals(a, b)那么你必须确保myEqualitycomaprer.GetHashCode(a) == myEqualitycomaprer.GetHashCode(b).
它可以是与 相同的实现StagingDataRow.GetHashCode,但不一定。
\n\n\n传递给什么
\nIEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)?我正在寻找的对象还是列表中的对象?两个都?让实例方法接受自身作为参数会很奇怪......
好吧,现在我希望你已经明白实现的对象IEqualityComparer<T>是一个不同的对象,所以这应该是有道理的。
请阅读我关于在 C# 中使用 IEqualityComparer 接口和 EqualityComparer 类的答案,以获取更深入的信息。
\n| 归档时间: |
|
| 查看次数: |
5756 次 |
| 最近记录: |