首页 > 解决方案 > 当使用类作为字典的键时:是否有可能指定哪个类属性/变量确定键

问题描述

我尝试使用简化的源代码来解释我的问题。

我的课程是例如:

public class House
{
  public House(...)
  {
    address = ...;
    owner = ...;
  }

  public string address; //Unique variable
 
  public string owner; //Not unique variable
}

在某些时候,我需要一个字典,其中“House”作为键,例如布尔值作为值。例如

var doesTheHouseOwnerHaveDept= new Dictionary<House,bool>();

然后,我遇到的问题是字典“doesTheHouseOwnerHaveDept” - 当然 - 充满了重复项,因为通过考虑地址和所有者,如果一个人拥有多个房屋,则存在多个唯一的“密钥对”。

因此,是否有可能修改类,使得只有“house”类中的“owner”变量用于指定字典“doesTheHouseOwnerHaveDept”的键?

即,当所有者例如“Max”在地址“A”和“B”拥有房子时,先到先得,只有一个“房子”实例将被添加到字典“doesTheHouseOwnerHaveDept”中。

我知道在前面的示例中,可以通过其他更直观的方式轻松解决问题,但我没有更好的主意,并且想避免发布原始源代码。

感谢一百万您的支持和努力!:)

标签: c#dictionarykey

解决方案


如果您希望owner(在此简化代码中)成为Key您的,Dictionary您将需要覆盖Equalsand GetHashCode。覆盖两者很重要,否则它将不起作用。

这是该类的一个示例House
如果您创建两个具有相同所有者的房屋并尝试将它们添加到对象KeyHouse对象的字典中,则会给您一个错误

Edit
Here an importand edit from @l33t
“不要使用公共字段。而是使用带有私有设置器的属性。GetHashCode() 中使用的任何值都必须是不可变的,否则您的对象将丢失(例如在字典中),再也找不到了。


public class House
{
    public House(string address, string owner)
    {
        this.Address = address;
        this.Owner = owner;
    }

    public string Address; //Unique variable

    public string Owner
    {
        get;
        private set; //Private setter so the owner can't be changed outside this class because it if changes and the object is already inside 
                        // a dictionary it won't get notified and there will be two objects with the same 'Key'

    }

    public override bool Equals(object obj)
    {
        if (!(obj is House)) return false;

        var toCompare = (House) obj;
        return this.Owner == toCompare.Owner; //Just compare the owner. The other properties (address) can be the same
    }

    public override int GetHashCode()
    {
        return Owner.GetHashCode(); //Just get hashcode of the owner. Hashcode from the address is irrelevant in this example
    }

推荐阅读