VisualBasic.NETには、CallByNameという関数がある。
リフレクションという物の簡易版で、実行時に文字列から、プロパティ名やメソッド名を指定できる。
まぁ、ざっくりとコードをかく。(テストコードの環境は、ASP.NET)
まず、Hotelというクラスがあるとする。
Public Class Hotel
Private _HotelName As String = "ホゲホテル"
Property HotelName() As String
Get
Return _HotelName
End Get
Set(ByVal value As String)
_HotelName = value
End Set
End Property
Public Function GetNews() As String
Dim content As String = "お風呂を改装しました。"
Return content
End Function
End Class
このとき、プロパティやメソッドにアクセスする際に、文字列から指定できる。
Dim hotel As New Hotel()
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Write(hotel.HotelName & "<br>")
Response.Write(CallByName(hotel, "HotelName", CallType.Get) & "<br>")
CallByName(hotel, "HotelName", CallType.Set, "モゲホテル")
Response.Write(CallByName(hotel, "HotelName", CallType.Get) & "<br>")
Response.Write(CallByName(hotel, "GetNews", CallType.Method) & "<br>")
Response.Write(GetRoomName(2) & "<br>")
End Sub
CallByNameの第一引数にオブジェクトを渡し、第二引数にプロパティ名やメソッド名を入れて、第三引数に、プロパティのGetなのかSetなのかメソッドなのかを入れる。(Letってもあるが多分使わない)
基本的に、CallByNameは、普通にアクセスしたときより遅く、わざわざ使うメリットはない。
主に、デバッグ等の開発のお助け等々で使用されるだけである。
が、たまに使える時がある。
それは、ため息が出るような数字の連続に出会った時などである。
「ホテルクラスに部屋名を持たせたい。」
「小さいホテルだし10部屋ほどかな。」
そして、下記のようなものがHotelクラスに追加され既に運用されている。
Private _RoomName1 As String = ""
Property RoomName1() As String
Get
Return _RoomName1
End Get
Set(ByVal value As String)
_RoomName1 = value
End Set
End Property
Private _RoomName2 As String = ""
Property RoomName2() As String
Get
Return _RoomName2
End Get
Set(ByVal value As String)
_RoomName2 = value
End Set
End Property
Private _RoomName3 As String = ""
Property RoomName3() As String
Get
Return _RoomName3
End Get
Set(ByVal value As String)
_RoomName3 = value
End Set
End Property
'10まで 略
このような、コードで延々と書かれているときは、CallByNameが役に立つ。
if文やwhile文でひたすら分岐させる方法で書くと下記のようになる
Private Function GetRoomName(ByVal id As String) As String
Dim rName As String = ""
If id = 1 Then
rName = hotel.RoomName1
End If
If id = 2 Then
rName = hotel.RoomName2
End If
If id = 3 Then
rName = hotel.RoomName3
End If
Return rName
End Function
3つだから、いいが、部屋数が10個も20個もあると発狂しそうになる。
配列やリストに入れるなりで書き直したくなるが、すでに運用されてたり、データベース等と連携してデータベースのほうも1,2,3という悲惨な状態だと、手が付けられない。
さらにこれに部屋ごとの情報を入れたいとかなると、RooNameInfo1、RooNameInfo2などとなると・・・・。
そんな時に、文字列から直接アクセスできるCallByNameが重宝する。
さきほどの関数を書きなおすと、
Private Function GetRoomName(ByVal id As Integer) As String
Return CallByName(hotel, "RoomName" & id.ToString(), CallType.Get)
End Function
一行で済む。
もちろん、動作は遅くなるとは思うが、刺身にタンポポ乗せるような作業を、手作業でやるようなこと精神衛生上よろしくない。
参考:
http://msdn.microsoft.com/ja-jp/library/chsc1tx6%28v=vs.90%29.aspx