コードは、このようなものに見えたところ、私はオンライン場所のカップルに遭遇しました:GetHashCode()evil内でF#のハッシュ関数を使用していますか?
[<CustomEquality;NoComparison>]
type Test =
| Foo
| Bar
override x.Equals y =
match y with
| :? Test as y' ->
match y' with
| Foo -> false
| Bar -> true // silly, I know, but not the question here
| _ -> failwith "error" // don't do this at home
override x.GetHashCode() = hash x
をしかし、私はFSIで上記を実行すると、私はTest
のインスタンスにhash foo
を呼び出すとき、またはIのいずれかのとき、プロンプトは返しませんfoo.GetHashCode()
に直接電話してください。
let foo = Test.Foo;;
hash foo;; // no returning to the console until Ctrl-break
foo.GetHashCode();; // no return
私はそれ容易に証明できなかったが、それは上記のコードを意味し、オブジェクト上のhash x
通話GetHashCode()
は、危険であることを示唆しています。それともちょうどFSIの演奏ですか?
私は上記のようなコードは "カスタム等価を実装してくださいが、デフォルトとしてハッシュ関数を残してください"という意味だと思いました。
私はこのパターンを別の方法で実装しましたが、hash
がちょうどGetHashCode()
を呼び出し、永遠のループにつながると仮定して正しいかどうか疑問に思っています。余談として
、FSI内部の平等を使用することは、比較の前に
更新:これは上記の例のように意味があります。GetHashCode()
を呼び出さないか、またはそれが何か他のものをすることを示唆し、すぐに戻ります。
x.Equals
はGetHashCode()
を呼び出さず、等価演算子はGetHashCode()
ではなくEquals
を呼び出します。 GetHashCode()
メソッドがオーバーライドされた場合
_ "オブジェクトのメンバの一部を手動でハッシュしているときでしょうか" _、はい、これは実際には 'string *( 'T - >' U ')に似た、私は文字列に 'hash s'を呼び出しました(無限の再帰はありません)。しかし、私はそれらのスレッドをオンラインで見たとき、私は、ちょっと、それを試してみました...この質問につながる。 – Abel
ソースコードへのポインタをありがとう。そして例外に関するあなたのコメントについて:あなたは正しい、悪い例のコードです...私はだまされていました。 – Abel
@Abelええ、あなたはおそらくこれを知っていると思っていましたが、この質問/回答を見る他の人々のためにそこに置く価値があると思っていました。 – TheInnerLight