A struct type is a value type that is typically used to encapsulate small groups of related variables.
Structs inherit from
System.ValueType. This type overrides
GetHashCode. The implementation of
Equals on each field and returns true if all fields are equal. If there are no GC references in this object it avoids reflection and uses
GetHashCode is a a little bit complex. It looks for the first non-static field and get its hashcode. If the type has no non-static fields, it returns the hashcode of the type.
The default implementation is very generic and work for any value type. The drawback is that the implementation is not performant! The
GetHashCode methods are used when you check 2 instances are equal (
a == b or
a.Equals(b)) or when you use the type as the key of a
Dictionary<TKey, TValue>, or a similar type. This means that when you use a
T is a struct with the default implementation, the performance may be sub-optimal. A simple benchmark shows how slow
GetHashCode are compared to specific implementation when used with a
Now, you understand how important it is to override
GetHashCode if you want those to be performant!
#Generate equality members
Instead of writing the
GetHashCode methods yourself, you can generate them. In addition, you can generate operators and implement
This will produce the following code:
internal struct StructWithOverrides : IEquatable<StructWithOverrides>
public int Value;
public StructWithOverrides(int value)
Value = value;
public override bool Equals(object obj)
return obj is StructWithOverrides overrides && Equals(overrides);
public bool Equals(StructWithOverrides other)
return Value == other.Value;
public override int GetHashCode()
public static bool operator ==(StructWithOverrides left, StructWithOverrides right)
public static bool operator !=(StructWithOverrides left, StructWithOverrides right)
return !(left == right);
It is just a matter of seconds to get a performant struct!
#Detect missing overrides using a Roslyn Analyzer
You can check if you should implement
GetHashCode for structs in your applications using a Roslyn analyzer. The good news is the free analyzer I've made already contains rules for that: https://github.com/meziantou/Meziantou.Analyzer.
You can install the Visual Studio extension or the NuGet package to analyze your code:
Do you have a question or a suggestion about this post? Contact me!