有时我需要没有字段的值对象(消息头,模式等),例如:
abstract class RequestHeader
{
}
sealed class FirstRequestHeader : RequestHeader
{
}
我在以下方法中使用它们:
partial class Server
{
private readonly IReadOnlyDictionary<RequestHeader, Action<object>> requestMap;
public void ProcessRequest(RequestHeader header, object request)
{
requestMap[header](request);
}
}
在这种情况下,GetHashCode
和Equals
方法的默认实现完全符合我的需要,因为我可以使用单身。
但由于FirstRequestHeader
是一个不可变的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
覆盖==
运算符和Equals
方法很简单。
但在这种情况下,覆盖GetHashCode
方法的正确或推荐方法是什么?
我可以期待一些答案(都有一些缺点):
GetType
方法但是没有通过搜索确认的假设
那么,你会做什么?
答案 0 :(得分:3)
如果没有与该类关联的数据,则只创建一个实例。
sealed class FirstRequestHeader : RequestHeader
{
public static readonly FirstRequestHeader Value = new FirstRequestHeader();
private FirstRequestHeader()
{
}
}
答案 1 :(得分:2)
每种类型的硬编码常量哈希码
如果您希望将两个“相同”的对象视为相等(并且没有字段或您的实例相同),这绝对是可行的方法。
添加一个新字段,我假设您不会以任何有意义的方式进行修改,结果相同,只是过于复杂。对于其他两种方法也可以这样说。
请注意,您可以选择任何值 - 您不必担心不同类型之间可能的哈希代码冲突,因此请保持简单。
答案 2 :(得分:1)
如果您希望所有实例具有相同的哈希码而不使用常量,您还可以使用该类型的哈希码:
public class FirstRequestHeader
{
public override int GetHashCode()
{
return this.GetType().GetHashCode();
}
}