且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么KeyValuePair不覆盖Equals()和GetHashCode()?

更新时间:2023-11-28 17:29:46

其他答案指出,您可以免费"获得相等性和哈希,因此您无需覆盖它们.但是,您得到的货款是多少?默认情况下,相等和哈希的实现方式(1)在某些情况下不是特别有效,并且(2)可以进行按位比较,因此可以执行诸如比较负零和正零双精度在逻辑上相等时是不同的事情.>

如果您希望您的结构经常用于需要相等和哈希的上下文中,那么您应该编写两者的自定义实现并遵循适当的规则和准则.

https://ericlippert.com/2011/02/28/guidelines- and-rules-for-gethashcode/

因此,要回答您的问题:为什么没有人针对特定类型呢?可能是因为他们认为这样做与改进基础类库所需要做的所有其他事情相比,并不能很好地利用他们的时间.大多数人不会比较键值对是否相等,因此优化它可能不是一个高优先级.

这当然是推测性的;如果您实际上想知道某天某件事未完成的原因,那么您将必须找出所有所有人的人不做那个动作,然后问他们那天他们还在做什么,更重要.

I was going to use KeyValuePair in a comparison-intensive code and was perplexed checking how it is implemented in .NET (s. below)

Why does it not override Equals and GetHashCode for efficiency (and not implement ==) but instead uses the slow reflection-based default implementation?

I know that structs/value types have a default implementation based on reflection for their GetHashCode() and Equals(object) methods, but I suppose it is very inefficient compared to overriding equality if you do a lot of comparisons.


EDIT I made some tests and found out that in my scenario (WPF Lists) both default KeyValuePair and my own implementation of a struct overriding GetHashCode() and Equals(object) are both much more slow then an implementation as a class!


http://referencesource.microsoft.com/#mscorlib/system/collections/generic/keyvaluepair.cs,8585965bb176a426

// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
/*============================================================
**
** Interface:  KeyValuePair
** 
** <OWNER>[....]</OWNER>
**
**
** Purpose: Generic key-value pair for dictionary enumerators.
**
** 
===========================================================*/
namespace System.Collections.Generic {

    using System;
    using System.Text;

    // A KeyValuePair holds a key and a value from a dictionary.
    // It is used by the IEnumerable<T> implementation for both IDictionary<TKey, TValue>
    // and IReadOnlyDictionary<TKey, TValue>.
    [Serializable]
    public struct KeyValuePair<TKey, TValue> {
        private TKey key;
        private TValue value;

        public KeyValuePair(TKey key, TValue value) {
            this.key = key;
            this.value = value;
        }

        public TKey Key {
            get { return key; }
        }

        public TValue Value {
            get { return value; }
        }

        public override string ToString() {
            StringBuilder s = StringBuilderCache.Acquire();
            s.Append('[');
            if( Key != null) {
                s.Append(Key.ToString());
            }
            s.Append(", ");
            if( Value != null) {
               s.Append(Value.ToString());
            }
            s.Append(']');
            return StringBuilderCache.GetStringAndRelease(s);
        }
    }
}

As the other answers point out, you get equality and hashing "for free", so you don't need to override them. However, you get what you pay for; the default implementations of equality and hashing are (1) not particularly efficient in some cases, and (2) may do bitwise comparisons, and hence can do things like compare negative zero and positive zero doubles as different when logically they are equal.

If you expect that your struct will frequently be used in contexts that require equality and hashing, then you should write custom implementations of both and follow the appropriate rules and guidelines.

https://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

So, to answer your question: why did no one do so for a particular type? Likely because they did not believe that doing so was a good use of their time compared to all the other things they had to do to improve the base class libraries. Most people do not compare key-value pairs for equality, so optimizing it was probably not a high priority.

This is of course conjectural; if you actually want to know the reason why something did not get done on a particular day, you're going to have to track down all the people who did not do that action and ask them what else they were doing that was more important on that day.