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):
GetType methodBut no assumption was confirmed by searching
So, what would you do?
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()
{
}
}
hardcode constant hashcode for each type
If you want two "identical" objects to be treated as equal (and with no fields or your instances are identical), this is definitely the way to go.
Adding a new field, which I assume you won't modify in any meaningful way results in the same, just overcomplicates this. Same can be said for the other two approaches.
Please note that you can choose any value - you do not need to worry about possible hash code collisions between different types, so keep it simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With