Home > other >  Convert an unknown structure to an untyped Object in VB.NET
Convert an unknown structure to an untyped Object in VB.NET

Time:10-01

I'd like to convert an unknown basic structure to an Object (no type here).

I'm building a library that will be used by many users to extract data from my system but don't want to do a new function for everyone of them. They have to know what will be the result.

In vb, it is possible to create an Object with some properties and use it as it is a regular Class like so:

Dim myObj as New With { .name = "Matt", .age = "28" }
MsgBox( myObj.name & " is now " & myObj.age & " years old.")

So far, so good.

Next step : my user will give me some instructions that I need to extract data from various DBs, and I've no idea of what the result will be.

What I know after the execution is a list of String containing the columns of the result set and, of course a (set of) rows.

And here is the problem of course

My function (for a single row) so far:

Public Function GetData(ByVal instructions as String) as Object ' User is supposed to know what will be inside, instructions is as XML describing DB, table, query, ...
   ' Do what is needed to retrieve data
   ' Here I have a variable cols As List(Of String) ' e.g. ("BP", "NAME", "VAT")
   Dim o As New With ???
   Return o
End Function

What I've tried: build a fake JSon on the fly, and try to Deserialize to Object. But even if it seems to work, I (and the user) can't access the property as in my top piece of code like:

MsgBox(o.BP)

I know that I could do

Public Function GetData(Of T As {New})(ByVal instructions as String) As T
   Dim o As T
   ' Use some Reflexion to TryInvokeMember of T
   Return o
End Function

But I wanted to remove the hassle to create a class to use my code. Plus, My librairy will be use in a webservice and the class of the user is then unknown.

CodePudding user response:

One approach could be - to use Dictionary(Of String, Object)

Public Function GetData(instructions as String) As Dictionary(Of String, Object)
    Dim data = ' Load data
    Dim columns As String() = { "BP", "NAME", "VAT" }

    Return columns.ToDictionary(
        Function(column) column,
        Function(column) data.GetByColumnName(column)
    )
End Function

` Usage

Dim result = GetDate("instructions: ['BP', 'NAME']")
' Because user knows it is Integer
Dim bpValue = DirectCast(result.Item("BP"), Integer)

CodePudding user response:

Thanks to @GSerg, @Fabio and a few other searches about ExpandoObject, I did it !

Imports System.Dynamic  

Dim o As Object = New ExpandoObject()
For Each col In cols
    DirectCast(o, IDictionary(Of String, Object)).Add(col, row.GetString(col))
Next
  • Related