Search code examples
c#immutabilitygethashcodevalue-objects

Overriding GetHashCode() for value objects without fields


Sometimes I need value objects without fields (message headers, schemas, etc.), for example:

abstract class RequestHeader
{
}

sealed class FirstRequestHeader : RequestHeader
{
}

I use them in methods like:

partial class Server
{
    private readonly IReadOnlyDictionary<RequestHeader, Action<object>> requestMap;

    public void ProcessRequest(RequestHeader header, object request)
    {
        requestMap[header](request);
    }
}

In this case default implementation of GetHashCode and Equals methods totally fits my needs, because I can use singletons.

But since FirstRequestHeader is an immutable value object I want it to behave like a real value object:

var a = new FirstRequestHeader();
var b = new FirstRequestHeader();
Console.WriteLine(a == b &&
    a.Equals(b) &&
    a.GetHashCode() == b.GetHashCode()); // False, but should be True

Overriding == operator and Equals method is easy.

But what is correct or recommended way of overriding GetHashCode method in this case?

I can expect some answers (all with some drawbacks):

  • hardcode constant hashcode for each type
  • generate one each execution and save it in a static field
  • use type's hashcode through GetType method
  • avoid empty objects (add a field)

But no assumption was confirmed by searching

So, what would you do?


Solution

  • If there is no data associated with the class then make only one instance.

    sealed class FirstRequestHeader : RequestHeader
    {
        public static readonly FirstRequestHeader Value = new FirstRequestHeader();
    
        private FirstRequestHeader()
        {
    
        }
    }