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