[英]Overriding GetHashCode() for value objects without fields
有時我需要沒有字段的值對象(消息頭,模式等),例如:
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
是一個不可變的值對象,所以我希望它的行為類似於真實值對象:
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
方法使用類型的哈希碼 但是沒有通過搜索確認任何假設
那么,你會怎么做?
如果沒有與該類關聯的數據,則僅創建一個實例。
sealed class FirstRequestHeader : RequestHeader
{
public static readonly FirstRequestHeader Value = new FirstRequestHeader();
private FirstRequestHeader()
{
}
}
每種類型的硬編碼常量哈希碼
如果您希望兩個“相同”的對象被視為相等(並且沒有字段或您的實例相同),那么這絕對是正確的方法。
添加一個新字段(我認為您不會以任何有意義的方式對其進行修改)會導致相同的結果,只會使此過程變得過於復雜。 對於其他兩種方法可以說相同。
請注意,您可以選擇任何值-您不必擔心不同類型之間可能發生的哈希碼沖突,因此請保持簡單。
如果希望所有實例具有相同的哈希碼而不使用常量,則還可以使用以下類型的哈希碼:
public class FirstRequestHeader
{
public override int GetHashCode()
{
return this.GetType().GetHashCode();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.