C#Dictionary中的KeyNotFoundException在根据内容更改属性值后,计算GetHashCode.为什么?

Rip*_*rot 2 c# hash dictionary

请参阅下面的代码.

            static void Main(string[] args)
            {
    // Create Dictionary
                var dict = new Dictionary<TestClass, ValueClass>();

    // Add data to dictionary
                CreateSomeData(dict); 

    // Create a List
                var list = new List<TestClass>();
                foreach(var kv in dict) {
    // Swap property values for each Key
    // For example Key with property value 1 will become 6
    // and 6 will become 1
                    kv.Key.MyProperty = 6 - kv.Key.MyProperty + 1;

    // Add the Key to the List
                    list.Add(kv.Key);
                }

// Try to print dictionary and received KeyNotFoundException.
                foreach (var k in list)
                {
                    Console.WriteLine($"{dict[k].MyProperty} - {k.MyProperty}");
                }
            }



    static void CreateSomeData(Dictionary<TestClass, ValueClass> dictionary) {
        dictionary.Add(new TestClass {MyProperty = 1}, new ValueClass {MyProperty = 1});
        dictionary.Add(new TestClass {MyProperty = 2}, new ValueClass {MyProperty = 2});
        dictionary.Add(new TestClass {MyProperty = 3}, new ValueClass {MyProperty = 3});
        dictionary.Add(new TestClass {MyProperty = 4}, new ValueClass {MyProperty = 4});
        dictionary.Add(new TestClass {MyProperty = 5}, new ValueClass {MyProperty = 5});
        dictionary.Add(new TestClass {MyProperty = 6}, new ValueClass {MyProperty = 6});
    }
Run Code Online (Sandbox Code Playgroud)

关键和价值类:

namespace HashDictionaryTest
{
    public class TestClass
    {
        public int MyProperty { get; set; }

        public override int GetHashCode() {
            return MyProperty;
        }
    }

}

namespace HashDictionaryTest
{
    public class ValueClass
    {
        public int MyProperty { get; set; }

        public override int GetHashCode() {
            return MyProperty;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我在Ubuntu上使用dotnet core 2.2.我出于好奇只做了这个测试.但令我惊讶的是,我得到了KeyNotFoundException.

我希望收到错误的值.但是,我收到了如上所述的例外情况.

我想知道的是,为什么我们得到这个错误?生成HashCode的最佳做法是什么,以便我们可以避免此类问题?

Eri*_*ert 5

我想知道的是,为什么我们得到这个错误?

GetHashCode 有指导方针,并且有规则.如果违反指南,则表现糟糕.如果违反规则,事情就会破裂.

你违反了规则.GetHashCode的一个规则当一个对象在一个字典中时,它的哈希码不能改变.另一个规则是相等的对象必须具有相同的哈希码.

你违反了规则,所以事情就被打破了.那是你的错; 不要违反规定.

生成HashCode的最佳做法是什么,以便我们可以避免此类问题?

有关规则和指南的列表,请参阅:

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