Link to home
Start Free TrialLog in
Avatar of Kelly Martens
Kelly Martens

asked on

Enum with Function Names

I have an enum like so:

Public Enum DataCalls
        GetTypedTable = 0
        Duplicate_Name_Check = 1
        Regular_Table = 2
        Second_Table = 3
        Third_Table = 4
        Template_Load = 5
    End Enum

These values represent function names. Enum 1 is function that returns as boolean. The rest are functions that return as datatables.

I am trying to craft a function that will allow me to cast these enum values and call their respective function.

This is wrong but...

Function Test(ByVal DataCall As String) As Object
        'How do we call the associated
        Dim number As Integer = [Enum].Parse(GetType(clData.DataCalls), DataCall)
        'we have its integer. With this information how do we call the function

    End Function

Second Question. If the function has parameters in this situation, how would you handle that?
SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Why that string parameter, instead of

Public Enum EnumDataCalls
  GetTypedTable = 0
  Duplicate_Name_Check = 1
End Enum

Function Test(ByVal DataCall As EnumDataCalls) As Object
End Function

Open in new window


p.s. can you explain, why you need to hide different functions like that instead of implementing them separately?
Avatar of Kelly Martens
Kelly Martens

ASKER

the idea behind it is they want all their data calls in one call because they wrap it in a separate thread. They didn't want to wrap each function with its own thread.

I like your approach better then the other one (or perhaps it is more clearly explained). The only issue I would have with this approach is if the function has parameters to pass I don't see how you would do it here....
Makes no sense. Whether you have

Public Enum EnumDataCalls
    GetTypedTable = 0
    Duplicate_Name_Check = 1
End Enum

Public Class Class1
    Public Function Test(ByVal DataCall As EnumDataCalls) As Object
    End Function

End Class

Open in new window



or

Public Class Class2
    Public Function GetTypedTable() As Object
    End Function
    Public Function Duplicate_Name_Check() As Object
    End Function
End Class

Open in new window


does not affect how you handle threading. The second approach also solves your parameter problem and allows strong typing. The resulting As Object could be defined more strictly.

What does

the idea behind it is they want all their data calls in one call because they wrap it in a separate thread.

mean? Can you rephrase this, give us more context and maybe some concrete or pseudo-code samples?

p.s. sounds like someone is trying to over-generalize something at the wrong place.
>>They didn't want to wrap each function with its own thread.
That will only happen if you specifically use another thread for the function.

ps.  Using my suggestion you handle things by what they are - a string is a string not an object, an int is an int not an object which allows the compiler to warn you when something is wrong at compile time.
LVL can you do your sample in a properly coded block please?
ste5an Well I am not the person asking for the requirement. I get what they are trying to do. One function to pass them all to. Declare the enum as a variable previously and then call the sub that kicks off the thread. Do a select case on the variable. Return the boolean or datatable as an object and cast appropriately. The problem is it is not that great a coding practice at all. But like I said... I don't write the requirements.

I do appreciate your both input on this very much.
'we have its integer. With this information how do we call the function
You could create an array (or List) of Func(Of T)'s. In this way, you can simply index the array using the enum value and invoke the Func:

e.g.

    Dim functions() As Func(Of Object) = { AddressOf GetTypedTable, AddressOf Duplicate_Name_Check, AddressOf Regular_Table, AddressOf Second_Table, AddressOf Third_Table, AddressOf Template_Load }
    Dim toCall As DataCalls = DataCalls.Second_Table    
    Dim result As Object = functions(toCall).Invoke()

Open in new window


Keep in mind that this is a very brittle approach. As you add (or remove, or rearrange) methods in either the array or the enum, you have to remember to update the other thing as well. It would be slightly better to wrap all of this up into a custom class, but you still don't get rid of the problem that way. You, at least, localize the things that belong together.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
well thanks to you all I got them to be willing to do something different though I am keeping that last code sample in my back pocket for a bit. Just wanted to say thank you for your all time. I do appreciate it.

I think I found a way to give them the separate thread for the data call being made though it isn't what they wanted. I am using a lambda expression to run the thread in each data call made. Not sure it will work yet as i havent done all functions. if interested let me know and i will put it here
if interested let me know and i will put it here

Sure, maybe you can get more clues and hints..
Sure would love to hear that.

Function Template_Load() As DataTable
        Dim da As New TableAdapter
        Dim tbl As New DataTable
        ErrorMessage = ""
        Dim thread As New Thread(
  Sub()


      Try
          da.Fill(tbl)
          'Return tbl
      Catch ex As Exception
          ErrorMessage = ex.Message
          'Return Nothing
      Finally
          da.Dispose()
      End Try
  End Sub
)
        thread.Start()
        If ErrorMessage = "" Then
            Return tbl
        Else
            Return Nothing
        End If
        thread.Abort()

    End Function
The selected answer--though not mentioned anywhere--is still a brittle approach. You have the same issue of having to update two places whenever new methods are added or old methods are removed.
ErrorMessage is undeclared in this snipped.

hmm, and please use the embed code button..
I am wondering if the thread.abort will never run.
@käµfm³d 👽:
Sure it is. But this is what you get, when you don't have clean requirements. But it also gives the upstream consumer the choice to use the requested "pragmatic" method or the native methods.
ErrorMessage is a globally declared string variable.

lets see I have never done that before. I will try here.
Function Template_Load() As DataTable
        Dim errormessage As String

        Dim da As New OleDbDataAdapter
        Dim tbl As New Datatable
        ErrorMessage = ""
        Dim thread As New Thread(
  Sub()


      Try
          da.Fill(tbl)
          'Return tbl
      Catch ex As Exception
          ErrorMessage = ex.Message
          'Return Nothing
      Finally
          da.Dispose()
      End Try
  End Sub
)
        thread.Start()
        If ErrorMessage = "" Then

            Return tbl
        Else
            Return Nothing
        End If
        thread.Abort()

    End Function

Open in new window

@Kelly: Can you explain, why you need threads? Just to keep the UI interactive? Cause the posted threading does not much more than that.
In this case you may take look at Asynchronous Execution in Visual Basic .NET. But you should also take a look at async/await.