我正在为在 .net 上运行的语言编写编译器,我想做的一件事是自动生成 GetHashCode 方法,但我有几个问题:
- 这可能吗,编译器是否对所涉及的类型足够了解以合理地实现该方法?
- 我应该为值类型、引用类型还是两者都这样做?
- 什么是编译器生成的合理的 GetHashCode 算法,包括对空属性的支持等等?
- 这是用我可以查看的另一种语言/编译器完成的吗?
- 如果这是不可能的或者是一个非常糟糕的主意,为什么?
谢谢
我正在为在 .net 上运行的语言编写编译器,我想做的一件事是自动生成 GetHashCode 方法,但我有几个问题:
谢谢
看看 C# 编译器对匿名类型做了什么。基本上它与我自己写的哈希相同:
public override int GetHashCode()
{
int hash = 17;
hash = 31 * hash + field1.GetHashCode();
hash = 31 * hash + field2.GetHashCode();
// etc
return hash;
}
(当然,您还需要进行一些无效性检查。)
我认为对不可变类型执行此操作(和相等覆盖)是个好主意,但通常不适用于可变类型。无论如何,值类型几乎总是不可变的——引用类型可以采用任何一种方式。您的语言是否有任何内置的不变性概念?当然,如果您的类型是“浅不可变”但包含覆盖GetHashCode
以指示对象的当前状态的可变类型,这将出错。无论如何,这种类型通常会很痛苦。
不过总的来说,我认为在许多情况下自动生成相等和哈希码是合理的——事实上,我也希望这也成为命名类型的 C# 5 的一部分:我想要一种简单的命名类型的方法,否则它们具有相同的特性作为匿名类型。