とりこらぼ。

Learn from yesterday,
live for today,
hope for tomorrow.

目次

Blog 利用状況

ニュース

プロフィール

  • 名前:とりこびと
    とるに足らない人間です。

  • Wankuma MVP
    for '平々凡々'

Web Site

  • Memo(Of T)

もうひとつの Blog

広告っぽい

書庫

日記カテゴリ

Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) -

というわけで、その3です。ここのところのエントリ具合は決してスタンスを変えたとかってわけじゃないです。

少し日が空いたので、その2へリンク→Visual Basic 2008 の新機能 - 匿名型 その2(キー プロパティ) -

さて、匿名型はコンパイラによって生成されているらしいのですが、実際にはどんな感じになっているんでしょうねぇ。気になります。とても。

というわけでまずはここらあたりを見てみます。

さくっとまとめてみると、

  • Object から直接継承する。
  • 指定した型のプロパティを宣言する。
  • ToString をオーバーライドする。
  • キー プロパティは読み取り専用プロパティとして宣言する。
  • キー プロパティがある場合は、EqualsGetHashCode をオーバーライドする。
  • キー プロパティがある場合は、System.IEquatable(Of T) インターフェイスを実装する。

で、Visual Basic Language Specification 9.0に書かれているサンプルを元に、以下の匿名型がどう宣言されるのかを書いてみますと、

Dim member = New With {Key .ID = 76, .Name = "とりこびと"}

こんな感じっぽいです。↓

Imports System
Friend Class AnonymousType    ' クラス名は多分違う。     Implements IEquatable(Of AnonymousType)
    Private ReadOnly _id As Integer     Private _name As String
    Public Sub New(ByVal id As IntegerByVal name As String)
        Me._id = id         Me._name = name
    End Sub
    Public ReadOnly Property ID() As Integer         Get             Return Me._id         End Get     End Property
    Public Property Name() As String         Get             Return Me._name         End Get         Set(ByVal value As String)             Me._name = value         End Set     End Property
    Public Overrides Function Equals(ByVal obj As ObjectAs Boolean
        Dim other As AnonymousType = TryCast(obj, AnonymousType)         Return Me.Equals(other)
    End Function
    Public Overloads Function Equals(ByVal other As AnonymousType) As Boolean _
    
Implements System.IEquatable(Of AnonymousType).Equals
        If other Is Nothing Then             Return False         End If
        If Not Object.Equals(Me._id, other._id) Then             Return False         End If
        Return True
    End Function
    Public Overrides Function GetHashCode() As Integer
        Dim hash As Integer = 0         hash = hash Xor Me.ID.GetHashCode()
        Return hash
    End Function
    Public Overrides Function ToString() As String
        Return "{ Key .ID = " & Me.ID & ", .Name = " & Me.Name & " }"
    End Function
End Class

ううむ・・・クラスのスコープは 'Friend' になるみたいですね。Equals のオーバーライドと、GetHashCodeのオーバーライドではキープロパティ が関係していますし、ToStringは宣言から文字列作ってますね。


あれ?そういえば、MSDN:匿名型の定義には以下のようなことが書かれていましたけど・・・

匿名型の定義には、既定のコンストラクタが含まれます。パラメータを必要とするコンストラクタは使用できません。

既定のコンストラクタってないよね・・・?


いったいどうなっているのでしょ?おしえてエラい人!!




あ、そうそう

明示的に名前を付けられた匿名型のプロパティは、これらの生成されるメソッドと競合することはできません。つまり、.Equals、.GetHashCode、または .ToString を使用してプロパティに名前を付けることはできません。

ですよ。

投稿日時 : 2008年1月11日 16:43

Feedback

# re: Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) - 2008/01/11 17:42 ダッチ

新機能を全く勉強していない私が想像で答えてみます。

Public Sub New(ByVal id As Integer, ByVal name As String)

これはパラメータを必要とするコンストラクタですよね。

でも New With で(With に注目)匿名型を作っています。
With はインスタンス生成後にプロパティ経由で値を設定するはずですから、引数ありのコンストラクタはコンパイラが生成していないんだと思います。
よって匿名型には既定のコンストラクタしか存在しません。
ということでしょうか。

# re: Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) - 2008/01/15 11:51 とりこびと

ダッチさん、コメントありがとうございます。

>With はインスタンス生成後にプロパティ経由で値を設定するはずですから、引数ありのコンストラクタはコンパイラが生成していないんだと思います。
>よって匿名型には既定のコンストラクタしか存在しません。

私も雰囲気的にはそれで納得なのですが、言語仕様として書かれている内容がそうではなかったので、首をかしげた次第です。

この件、調べられるところまで調べてみようと思っています。

# re: Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) - 2008/01/15 15:11 ダッチ

> 言語仕様として書かれている内容がそうではなかったので、首をかしげた次第です。
言語仕様が違ったのですか! それは確かに首をかしげてしまいますね。

> この件、調べられるところまで調べてみようと思っています。
おぉ、期待して待っております。

私も言語仕様を読んでみたいですけど何分英語なもんで・・・
言語仕様になんて書かれているかだけでも確認したいです orz

# re: Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) - 2008/01/15 15:20 Streetw☆

IDはRead Onlyなのに
With {Key .ID = 76
で設定できるところとか、Keyは特別なんですね。

それと例えば次の2つの匿名型
Dim a1 = New With {Key .Name = "test"}
Dim a2 = New With {Key .Name = DirectCast(Nothing, String)}
の場合、エントリで書かれてるコードだと
MessageBox.Show((a1.GetHashCode() = a1.Name.GetHashCode()).ToString())
MessageBox.Show(a2.GetHashCode().ToString())
の1つめは同じ値、2つめはヌルリが発生しそうなのに、そうならないです。

Visual Basic Language Specificationに書かれてるコードって、前の時もコンパイルできないコードが書かれてたけど、今回も11.10.4に書かれてるコードってReadOnly PropertyなのにSetが書かれてたりしてますね。
looks likeすぎ?w

C#だとKeyってあるのかなと思って検索してたら、C#では読み取り専用になるとかの違いもあるんですね。
検索したら、かるあさんのブログとかに書かれてました。
前にも読ませてもらってたのに、すっかり忘れてました。。。
そこからsiokoshouさんとこにたどると、C#ではKeyとか指定しなくてもGetHashCodeとかはオーバーライドされるみたいですね。

# re: Visual Basic 2008 の新機能 - 匿名型 その3(匿名型ってどんな感じに生成されるん?) - 2008/01/15 16:17 Streetw☆

さらに調べて、十中八九そうかもってことがわかりました。
とりこびとさんの調査結果と同じだといいな(デジャブw

# Visual Basic 2008 の新機能 - 匿名型 その4(既定のコンストラクタを探しに行ってみた。) - 2008/01/23 18:22 とりこらぼ。

Visual Basic 2008 の新機能 - 匿名型 その4(既定のコンストラクタを探しに行ってみた。) -

# Visual Basic 2008 の新機能 - 匿名型 その4(既定のコンストラクタを探しに行ってみた。) - 2008/01/23 18:42 とりこらぼ。

Visual Basic 2008 の新機能 - 匿名型 その4(既定のコンストラクタを探しに行ってみた。) -

# エルメス 店舗 2012/10/21 0:21 http://www.hermespurses-outlets.com/

??????銈?倣?????????????^????????伃??季

タイトル
名前
Url
コメント