Access VB property based on name as string - Fastest Option

百般思念 提交于 2019-12-13 07:37:00

问题


I'm developing an ASP.NET MVC web app in VB and I am required to output a set of data to a table format, and to allow the user to configure the order and presence of columns from an available set. The data set is stored as a list of the object type representing the row model.

Currently, I implement this using CallByName. Iterating over an ordered list of property names and outputting the value from the instance of the row model. However, based on testing this seems to be a major bottleneck in the process.

I've seen a recommendation to store delegates to get the property, against the string representation of the property's name. So, I can presumably do something like this:

Public Delegate Function GetColumn(ByRef RowObj As RowModel) As String

Dim GetPropOne As GetColumn = Function(ByRef RowObj As RowModel) RowObj.Prop1.ToString()

Dim accessors As New Hashtable()

accessors.Add("Prop1", GetPropOne)

Then, loop through and do something like this:

Dim acc As GetColumn = accessors(ColumnName)

Dim val As String = acc.Invoke(currentRow)

It looks faster, but it also looks like more maintenance. If this is indeed faster, is there a way I can dynamically build something like this? I'm thinking:

Public Delegate Function GetObjectProperty(Instance As Object) As Object

For Each prop In GetType(RowModel).GetProperties()
    Dim acc As GetObjectProperty = AddressOf prop.GetValue
    columns.Add(prop.Name, acc)
Next

Dim getColVal As GetObjectProperty = columns(ColumnName)

Dim val As String = getColVal.Invoke(currentRow).ToString()

Open to suggestions for different approaches.


回答1:


I do a similar thing to turn a SOAP response into a Data Table

Public Function ObjectToDataSource(objName) As DataSet
    Dim CollName = ""
    Dim ds As New DataSet()
    For Each m As System.Reflection.PropertyInfo In objName.GetType().GetProperties()
        If m.CanRead Then
            If InStr(m.PropertyType.ToString, "[]") <> 0 Then
                CollName = m.Name
                Exit For
            End If
        End If
    Next
    Dim CollObj
    CollObj = CallByName(objName, CollName, CallType.Get)
    If CollObj.length = 0 Then
        Call EndTask("No Supply Chains to display", "Royal Mail failed to return Supply Chain information for these credentials", 3)
    Else
        Dim dt_NewTable As New DataTable(CollName)
        ds.Tables.Add(dt_NewTable)
        Dim ColumnCount = 0
        For Each p As System.Reflection.PropertyInfo In CollObj(0).GetType().GetProperties()
            If p.CanRead Then
                If p.Name <> "ExtensionData" Then
                    dt_NewTable.Columns.Add(p.Name, p.PropertyType)
                    ColumnCount = ColumnCount + 1
                End If
            End If
        Next
        Dim rowcount = CollObj.Length - 1
        For r = 0 To rowcount
            Dim rowdata(ColumnCount - 1) As Object
            For c = 0 To ColumnCount - 1
                rowdata(c) = CallByName(CollObj(r), dt_NewTable.Columns.Item(c).ToString, CallType.Get)
            Next
            dt_NewTable.Rows.Add(rowdata)
            rowdata = Nothing
        Next
    End If
    Return ds
End Function

This is specific to my needs in terms of getting CollName and not requiring ExtensionData




回答2:


If ColumnName is the same name as one of the RowModel's properties I don't see why you need the long workaround with delegates...

An extension method which gets only the property you want right now is both faster and consumes less memory.

Imports System.Runtime.CompilerServices

Public Module Extensions

    <Extension()> _
    Public Function GetProperty(ByVal Instance As Object, ByVal PropertyName As String, Optional ByVal Arguments As Object() = Nothing) As Object
        Return Instance.GetType().GetProperty(PropertyName).GetValue(Instance, Arguments)
    End Function
End Module

Example usage:

currentRow.GetProperty("Prop1")
'or:
currentRow.GetProperty(ColumnName)


来源:https://stackoverflow.com/questions/43868355/access-vb-property-based-on-name-as-string-fastest-option

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!