[VB.NET] CallByName 使いどころ

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

http://msdn.microsoft.com/ja-jp/library/microsoft.visualbasic.interaction.callbyname%28v=vs.110%29.aspx

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>