3

Consider a struct which does not contain any reference fields (only basic types and other structs).

Consider this struct will be used in collections and I want it to behave like a value type (ie int).

  • do I need to override operator== and operator!=?
  • do I need to override Equals?
  • do I need a copy constructor?
  • do I need to worry about assignment?
  • do I need to override GetHashCode?

1 Answer 1

3
  1. Depends on you, by default == and != will redirect to the default Equals implementation but it's considered better practice to use Equals directly instead of == or !=
  2. You should, by default Equals performs bitwise comparison on value types and reference equality on reference types, so if your struct contains fields that are reference types, you will need to override Equals to perform a proper comparison on them. Besides that, MSDN recommends to override Equals anyway, for performance benefits as well.

Particularly if your value type contains fields that are reference types, you should override the Equals(Object) method. This can improve performance and enable you to more closely represent the meaning of equality for the type.

  1. Structs are copied by default when passed between variables/methods, so there is no need to write a copy constructor. The only case I can think of is if your structs contains fields that are reference types and you want to create a copy constructor that performs deep copy on them, up to you.
  2. What do you mean worry about assignment?
  3. Yes. If you're going to use your struct as a member of HashSet or as a key in a Dictionary, you would want to provide a custom implementation of GetHashCode.

It is best to implement IEquatable to avoid boxing (default Equals accepts an object type, so your struct will have to undergo boxing to fit that type). Collections (Arrays, Dictionaries, etc...) will usually check if their members implement IEquatable, and will use IEquatable.Equals, so it's best to implement it. It is also recommended to implement the default Equals (from System.Object) and direct to to the IEquatable.Equals implementation. Example:

struct MyStruct : IEquatable<MyStruct>
{
    public int A { get; set; }

    public int B { get; set; }

    public bool Equals(MyStruct other)
    {
        return A == other.A && B == other.B;
    }

    public override bool Equals(object obj)
    {
        if (!(obj is MyStruct)) return false;
        return ((MyStruct)obj).Equals(this);
    }

    public override int GetHashCode()
    {
        return (A, B).GetHashCode();
    }
}

I also provided an example of how to implement GetHashCode, best way is to use the implementation of Tuple.

Again, implementing == and != is up to you The standard library (System, System.Collections, etc...) uses System.Equals or IEquatable.Equals to do comparison, and you should too.

So no, implementing == and != is not necessary.

Sign up to request clarification or add additional context in comments.

5 Comments

My question particularly asks about the case where no reference types are included. Please edit your answer accordingly
@kofifus Sorry, didn't catch if at first. If there are no reference types, my answer still holds, I just elaborated more on cases where you do have references types in the struct. I still advise to provide your own implementation of Equals, it would prove useful if you every change something - add reference types, would like to ignore a certain field.
so I can do without ==, != and Equals in this case ?
@kofifus Yes, Equals is enough, methods that act on members/keys of arrays/dictionaries call to .Equals for comparison, they don't use the == and != operators. I forgot to mention it but it's also best to implement IEquatable<YourStruct> because then you can avoid the unboxing (allocating the struct to memory) that happens when you call the default Equals(object)
I don't understand, what happens if I don't override ==, != and Equals ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.