-3

I currently have a C# class that appears as follows:

 namespace DBModel
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    public partial class ConnSrv
    {
        public int ID { get; set; }

        [Required]
        [StringLength(14)]
        public string Service { get; set; }

        [Required]
        [StringLength(14)]
        public string ConnectsToService { get; set; }

        public virtual Service Service1 { get; set; }

        public virtual Service Service2 { get; set; }
    }
}

In my main program, I'm creating hashsets to work with these objects. The problem I'm encountering is that I would like to be able to use operators such as Contains, Except, ExceptWith, UnionWith, and so on on these hashsets.

For an object of the ConnSrv to be considered "equal", the Service and ConnectsToService values have to be equal. As such, I realize that in some way, I will have to override the Equals and GetHashCode operators for the class. I'm just not sure how to do so, whether it's through a straight override of the object class, by implementing IEquatable or IEquatable, or through some other method. Below are a couple simple examples of what I would expect the end result to be once implemented. If I'm way out in left field, please let me know. Thanks in advance for your time.

        var testHS1 = new HashSet<ConnectingService>();

        testHS1.Add(test1);
        testHS1.Contains(test2); // Returns true

        var testHS2 = new HashSet<ConnectingService>();

        testHS2.Add(test1);
        testHS2.Add(test2);
        testHS2.Add(test3);

        testHS2.Except(testHS1); // Expect end result to only contain test3
LRP
  • 20
  • 4
  • What is your question? – Kyle Oct 05 '16 at 15:19
  • See also https://stackoverflow.com/questions/1378686/general-advice-and-guidelines-on-how-to-properly-override-object-gethashcode and the many other questions on Stack Overflow addressing this question. If after reviewing the available information you still problems, post a new question in which you include a good [mcve] that reliably reproduces or illustrates your problem, and explain clearly and precisely what your specific problem is. Explain what the code you have now does and what you want it to do instead and why you're unable to accomplish that. – Peter Duniho Oct 05 '16 at 16:30

3 Answers3

2

Here are the guidelines on how to override Equals

public override bool Equals(object obj)
{
    if (obj == null)
        return false;
    ConnSrv c = obj as ConnSrv;
    if (c == null)
        return false;
    if (ID == c.ID)
        return true;
    return false;
}

public override int GetHashCode()
{
    int result = ID.GetHashCode();
    return result;
}
Alex
  • 1,433
  • 9
  • 18
0

I'm just not sure how to do so, whether it's through a straight override of the object class, by implementing IEquatable or IEquatable, or through some other method.

An override of object.Equals and object.GetHashCode would be enough. You can optionally implement IEquatable as well, but for reference types the only benefit is a minute performance improvement since you don't have to cast from object. If you implement IEquatable you ALSO have to override object.Equals(object) and object.GetHashCode().

What's more important when using HashSet is that the rules of GetHashCode are followed, specifically that two "equal" objects have identical hash codes.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
0

Thank you Alex! That pointed me down the right path. I added the following code and appear to be off to the races.

    public override int GetHashCode()
    {
        return (Service.GetHashCode() * ConnectsToService.GetHashCode()).GetHashCode();
    }

    public bool Equals(ConnectingService c1)
    {
        return c1.Service == this.Service && c1.ConnectsToService == this.ConnectsToService;
    }
LRP
  • 20
  • 4