代码之家  ›  专栏  ›  技术社区  ›  Wesley Wiser

编译器生成的GetHashCode()。

  •  3
  • Wesley Wiser  · 技术社区  · 14 年前

    我正在为运行在.NET上的语言编写编译器,我希望它能自动生成gethashcode方法,但我有几个问题:

    • 这是可能的吗?编译器是否对所涉及的类型有足够的了解,以便对实现该方法做合理的工作?
    • 我应该对值类型、引用类型或两者都这样做吗?
    • 编译器生成的合理的gethashcode算法是什么,包括对空属性的支持等等?
    • 这是用我能看到的另一种语言/编译器完成的吗?
    • 如果这不可能或是一个很坏的主意,为什么?

    谢谢

    1 回复  |  直到 14 年前
        1
  •  2
  •   Jon Skeet    14 年前

    看看C编译器对匿名类型做了什么。基本上,它和我自己写的是同一种哈希:

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

    (当然,你也需要一些无效检查。)

    我认为对不可变类型执行此操作(和相等重写)是一个好主意,但一般来说 对于可变类型。无论如何,值类型应该几乎总是不可变的-引用类型可以采用任何一种方式。您的语言是否有任何不可变的内置概念?当然,如果您的类型是“Shallow-Immutable”,但包含可重写的可变类型,则会出错。 GetHashCode 指示 现在的 对象的状态。无论如何,这样的类型通常是痛苦的。

    不过,总的来说,我认为在许多情况下自动生成相等和哈希代码是合理的——事实上,我希望这也是C 5中命名类型的一部分:我希望 命名 与匿名类型具有相同功能的类型。