Key キーワードでは GetHashCode と Equals がオーバーライドされるみたい

昨日の Key についてのエントリで ひろえむさん からこんなコメントをいただいたので、少し調べてみました。

ひろえむさん wrote:
Equalsって確か今はGetHashCodeの値を比較していたんですよね?
これで等価判定をしていたように思うけど、これがKeyを指定することでOverridesされるんでしょうか? 
それとも、GetHashCode側がOverridesされるんでしょうか?


とりあえず、
まずは昨日のコードを少し変えてこんなコードを実行してみました。
Dim karua1 = New With {Key.name = "karua", Key.attribute = "VB.NET", .notes = "test"}
Dim karua2 = New With {Key.name = "karua", Key.attribute = "VB.NET", .notes = "testtest"}
Dim karua3 = New With {Key.name = "karua", Key.attribute = "VB6" , .notes = "test"}
Dim karua4 = New With {.name = "karua", .attribute = "VB.NET", .notes = "test"}
Dim karua5 = New With {.name = "karua", .attribute = "VB.NET", .notes = "testtest"}

Debug.WriteLine("karua1=" & karua1.GetHashCode().ToString())
Debug.WriteLine("karua2=" & karua2.GetHashCode().ToString())
Debug.WriteLine("karua3=" & karua3.GetHashCode().ToString())
Debug.WriteLine("karua4=" & karua4.GetHashCode().ToString())
Debug.WriteLine("karua5=" & karua5.GetHashCode().ToString())

GetHashCode の結果はこうなります。
karua1=-1397422136
karua2=-1397422136
karua3=-359881569
karua4=36181605
karua5=28068188

Key キーワードが宣言された匿名型は Key以外 を変更しても HashCode が変化しないのがわかります。

続いて IL Disassembler で吐き出された IL をのぞいてみます。
画像

Key が宣言されている匿名型 VB$AnonymousType_0`3 と 通常の匿名型 VB$AnonymousType_1`3 が宣言されていることがわかります。

また Key が宣言されている匿名型では、GetHashCode:Int32 と Equals:bool(object) がオーバーライドされ、Equals:bool(class VB$AnonymousType_0`3 がオーバーロードされていることがわかります。
VB$AnonymousType_1`3 の Eauals は スパークラス の Equals を呼んでいるので、単なるオブジェクトの比較になります。

この記事へのコメント

ひろえむ
2007年07月26日 19:33
わざわざ、調べてくださってありがとうございますm(__)m

ということは結論から言うとType Safeではないんですねー(^^;
ひろえむ
2007年07月26日 19:33
わざわざ、調べてくださってありがとうございますm(__)m

ということは結論から言うとType Safeではないんですねー(^^;

この記事へのトラックバック

  • 匿名型ってVBとC#で動作が違うのね。

    Excerpt: NAL さんのこの日記を見ていて VB と C# で匿名型の動作が違うということに初めて気づいた。 C#の匿名型はメンバがすべて読み取り専用のプロパティとして宣言されるため、最初に宣言した時に設定し.. Weblog: かるあ のメモ racked: 2007-09-17 01:17