1

I try to explain my question by using simplified source code.

The class I have is e.g.:

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

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

At some point, I need a dictionary which has the "House" as key and e.g. a boolean as value. E.g.

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

Then, I have the problem that the dictionary "doesTheHouseOwnerHaveDept" is - of course - full of duplicates since, by considering the address and owner, multiple unique "key pairs" exist if a person owns multiple houses.

Thus, is there a possibility to modify the class such that only the "owner" variable within the class "house" is used for specifying the key of the dictionary "doesTheHouseOwnerHaveDept"?

I.e., when an owner e.g. "Max" owns the house at address "A" and "B", then, first come, first serve like, only one "House"-instance will be added to the dictionary "doesTheHouseOwnerHaveDept".

I know that in the previous example, the problem could easily be solved in other more intuitional ways, but I did not have a better idea and wanted to avoid posting original source code.

Thanks a million for your support and effort! :)

Confucius
  • 37
  • 5
  • 1
    Does this answer your question? [When do we do GetHashCode() for a Dictionary?](https://stackoverflow.com/questions/1407380/when-do-we-do-gethashcode-for-a-dictionary) – Renat Oct 07 '20 at 09:41
  • 2
    This should help :) https://stackoverflow.com/questions/6999191/use-custom-object-as-dictionary-key – Ben Oct 07 '20 at 09:41
  • Ahh thanks to you both! :-) – Confucius Oct 07 '20 at 10:15

1 Answers1

1

If you want the owner (in this simplified code) to be the Key of your Dictionary you will need to override Equals and GetHashCode. It is important to override both otherwise it will not work.

Here an example of the House class:
If you create two houses with the same owner and try to add them to a dictionary where the Key is the House object it would give you an error

Edit
Here an importand edit from @l33t:
"Do not use a public field. Instead use a property with a private setter. Any value used in GetHashCode() must be immutable or your objects will get lost (in e.g. a dictionary), never to be found again."


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
    }
Adrian Efford
  • 473
  • 3
  • 8
  • 1
    And what would happen if you change `Owner` after adding the object to a dictionary? – l33t Oct 07 '20 at 10:28
  • @l33t Heeii. Really nice question !! I dind't know the answer till I tried it... Unfortunately the dictionary doesnt notify that change and accepts both entries... Any ideas on how to solve it? – Adrian Efford Oct 07 '20 at 11:10
  • 2
    Do not use a public field. Instead use a property with a private setter. Any value used in `GetHashCode()` **must** be immutable or your objects will get lost (in e.g. a dictionary), never to be found again. – l33t Oct 07 '20 at 11:32
  • 2
    @l33t I edited my answer and added your comment with a link to your profile. tank you very much ! – Adrian Efford Oct 07 '20 at 11:45