编译器生成的GetHashCode()

3

我正在编写一个运行在 .net 平台上的语言编译器,我希望它能自动生成 GetHashCode 方法,但是我有几个问题:

  • 这是否可行,编译器对涉及的类型了解足够多,能够合理地实现该方法吗?
  • 我应该为值类型、引用类型还是两者都要生成 GetHashCode 方法?
  • 哪种合理的 GetHashCode 算法可以由编译器生成,包括对 null 属性的支持等等?
  • 有没有其他语言/编译器已经做到了这一点,可以供我参考?
  • 如果这不可行或是一个非常糟糕的想法,为什么呢?

谢谢!

1个回答

2

看看C#编译器为匿名类型做了什么。基本上它生成的哈希值与我自己会写的一样:

public override int GetHashCode()
{
    int hash = 17;
    hash = 31 * hash + field1.GetHashCode();
    hash = 31 * hash + field2.GetHashCode();
    // etc
    return hash;
}

(当然,你还需要进行一些空值检查。)

我认为对于不可变类型来说,这是一个好主意(并且重写相等性),但通常对于可变类型来说却不是。 值类型几乎始终应该是不可变的 - 引用类型可以双向使用。 你的语言是否具有不可变性的内置概念? 当然,如果您的类型是“浅不可变”的但包含重写GetHashCode以指示对象的当前状态的可变类型,则会出现问题。 这些类型通常也很痛苦。

总的来说,我认为在许多情况下自动生成相等性和哈希码是合理的 - 实际上,我希望这也成为C# 5中命名类型的一部分:我希望有一种简单的方式来为那些除了匿名类型之外具有相同特征的类型命名。


该语言没有内置的不可变性,可以将其想象成类似于C#-3的语言。空值检查只需要判断是否为空,不要调用GetHashCode函数,还有其他需要注意的吗? - Wesley Wiser
@wawa:就是这样。对于那些具有空值的字段,使用一些常量(例如0)。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接