c# - 如何使字典按值查找对象键

标签 c# collections overriding

在我的应用程序中,我需要使用自定义对象作为字典的键。 问题是通过引用比较, 就像我们都知道,在使用值类型时,比较工作是按值进行比较,但在对象中,它是按引用进行比较,所以即使对象相等,它们也会在内存堆中的不同位置出现问题,因此它返回 false

为了正确执行,我需要重写 Equals 和 GetHashCode 方法(如果我错了,请纠正我)

我覆盖了 Equals 方法并且它正在工作:

bool IsEqual = dictionaryList.Keys.First().Equals(compareKey); 返回 true。

我不知道如何针对我的情况覆盖 GetHashCode 方法(如果我需要的话)。

我得到的异常:

字典中不存在给定的键。 -

The given key was not present in the dictionary.

我怎样才能解决这个问题,或者我可能完全以错误的方式解决了这个问题......

谢谢

using System;
using System.IO;
using System.Threading;
using System.Linq;
using System.Collections.Generic;

public sealed class Program
{
    public class Options
    {
        public string x { get; set; }
        public string y { get; set; }
    }

    public class Data
    {
        public string myData { get; set; }
    }

    public class KeyClass
    {
        public int KeyNumber { get; set; }
        public List<Options> Options { get; set; }

        public override bool Equals(object obj)
        {
            KeyClass keyClass = obj as KeyClass;

            bool IsKeyNumberEqual = (KeyNumber == keyClass.KeyNumber);
            bool IsOptionsEqual = true;

            if (!(Options.Count == keyClass.Options.Count) || !IsKeyNumberEqual)
            {
                IsOptionsEqual = false;
            }
            else
            {
                for (int i = 0; i < Options.Count; i++)
                {
                    if (!(Options[i].x == keyClass.Options[i].x) ||
                        !(Options[i].y == keyClass.Options[i].y))
                    {
                        IsOptionsEqual = false;
                        break;
                    }
                }
            }

            return (IsKeyNumberEqual && IsOptionsEqual);
        }
    }

    public static void Main()
    {
        try
        {
            List<Options> optionsList = new List<Options>();
            optionsList.Add(new Options() { x = "x1", y = "y1" });
            optionsList.Add(new Options() { x = "x2", y = "y2" });

            Data someData = new Data() { myData = "someData" };
            Data getData = new Data();

            KeyClass dictionaryKey = new KeyClass() { KeyNumber = 1, Options = optionsList };
            KeyClass compareKey = new KeyClass() { KeyNumber = 1, Options = optionsList };

            Dictionary<KeyClass, Data> dictionaryList = new Dictionary<KeyClass, Data>();

            dictionaryList.Add(dictionaryKey, someData);

            bool IsEqual = dictionaryList.Keys.First().Equals(compareKey);

            getData = dictionaryList[compareKey];
        }
        catch (Exception ex)
        {
            string exMessage = ex.Message;
        }


    }
}

最佳答案

to do it right i need to override Equals and GetHashCode methods (i think correct me if i'm wrong)

你是对的。 .NET 要求比较相等的两个对象具有相同的散列码。这不仅限于字典。

简单的实现是让每个对象返回相同的哈希码。但是,虽然允许两个不同的对象具有相同的散列码,但您应该将这种情况保持在最低限度。当你有很多散列冲突时,字典和其他容器的性能会变差。

稍微好一点的实现是返回 KeyNumber(或 KeyNumber.GetHashCode())。如果您几乎从来没有相同的键号,如果相同的键号非常强烈地表明选项也将相同,那么这可能是一个足够好的实现。

最好的实现方式是将 KeyNumber 的哈希码和所有 Options 值组合起来,如 Matthew Watson 的回答。

关于c# - 如何使字典按值查找对象键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40343889/

相关文章:

c# - ActiveDirectory 域说明?

c# - .net FIFO "Queue"结合最后一个已知主题

java - 合并两个 "OnActivityResult"方法

java - onListItemClick (mNotesCursor) 的问题

c# - 在 ASP.NET 5 中请求作用域服务

c# - 使用 DateTime 查看本周的预订

c# - 如何分离此 Entity Framework 模型以防止内存错误?

java - xstream,如何将列表序列化为xml

swift - 集合之间的通用迭代

swift - 努力理解 Swift 3 用非可失败初始化器覆盖可失败初始化器