-1

I am trying to call a certain method (say method called "Mood") associated with a Enum value (e.g. Enum WorkDay : Monday, Tuesday, Wednesday etc.).
I can obviously do a select case and call certain methods as below.

Public Enum WorkDay
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
End Enum

Dim CurrentDay As Class1.WorkDay = Class1.WorkDay.Monday
    Select Case CurrentDay
        Case Class1.WorkDay.Monday
            Function_Monday()
        Case Class1.WorkDay.Tuesday
            Method_Tuesday()
        Case Class1.WorkDay.Wednesday
            Method_Wednesday()
        Case Class1.WorkDay.Thursday
            Method_Thursday()
        Case Class1.WorkDay.Friday
            Method_Friday()
    End Select

However, I have seen it done previously using an interface for the Enum to call methods in different classes. This means it's scalable by simply adding in a new class for newer Enum types, and therefore don't need to add in extra Case legs for newer Enum types (e.g. Saturday and Sunday). Can anyone possibly give me some template code for this Enum interface, as I just can't recreate it. I'm missing something!

David Wilson
  • 4,369
  • 3
  • 18
  • 31
  • 1
    Why don't your `Method` take `WorkDay` as argument? Then you only need one method and one call. Side-note: there is already the [`DayOfWeek`-enum](https://msdn.microsoft.com/en-us/library/system.dayofweek(v=vs.110).aspx) and you get the current with [`DateTime.DayOfWeek`](https://msdn.microsoft.com/en-us/library/system.datetime.dayofweek(v=vs.110).aspx): `Dim dow = Date.Today.DayOfWeek` – Tim Schmelter Feb 20 '17 at 13:49
  • 1
    Are you shure that you have seen this in .net? in java an enum can have methods and the enum-s methods can implement an interface. – k3b Feb 20 '17 at 14:06
  • It sounds like you're looking for an enum of classes? And you would like these classes to implement a specific interface, such that you could call Class1.WorkDay.GetMood()? I haven't seen anything like that in .Net. Perhaps you saw something like this, using attributes? http://stackoverflow.com/questions/25323406/calling-a-method-by-enum-attribute-in-c-sharp – Derrick Moeller Feb 20 '17 at 14:09

4 Answers4

1

This is easily handled by the Typesafe Enum Pattern, see this article (and the previous one linked from it) give a good overview.

Enhancing the Typesafe Enum Pattern

Here is an example of how your specific issue could be handled by this pattern (converted to VB .NET):

Public Class WorkDay
   ' private constructor

   Private Sub New(day As String)
       Me.Day = day
   End Sub

  Public Day As WorkDay

  Public Sub DoDayJob()
     ' do whatever need done for that day of the week
  End Sub

  Public Shared Monday As New WorkDay("Monday")
  Public Shared Tuesday As New WorkDay("Tuesday")
  Public Shared Wednesday As New WorkDay("Wednesday")
  Public Shared Thursday As New WorkDay("Thursday")
  Public Shared Friday As New WorkDay("Friday")
End Class

 'used like this (to assign the 'Monday' value)
 Dim day = Workday.Monday

I added a single method, however the class can be as complex as it needs to be.

Alex B.
  • 2,145
  • 1
  • 16
  • 24
David Culp
  • 5,354
  • 3
  • 24
  • 32
0

Is it not possible for you to pass the enum to your method? And execute logic based on that?

Some thing like the following

Function ProcessDay(DayOfWeek as WorkDay) As IWorkDay

    Select Case DayOfWeek
        Case WorkDay.Monday
             Return <<class that inherits IWorkDay>>

       Case WorkDay.Tuesday
             Return <<class that inherits IWorkDay>>


    End Select

End Function
ddeamaral
  • 1,403
  • 2
  • 28
  • 43
0

This seems to work for me - rather than have a Select Case statement This loop iterates through each Enum value and compares it to the Enum Variable and executes the method with the appropriate name that matches the Enum name

    For Each day As class1.WorkDay In System.Enum.GetValues(GetType(class1.WorkDay))
        If CurrentDay = day Then
            CallByName(Me, "Method_" & [Enum].GetName(GetType(class1.WorkDay), day), CallType.Method, Nothing)
        End If
    Next

You may need to change a few things depending on how your code is written, but the basic idea is there.

David Wilson
  • 4,369
  • 3
  • 18
  • 31
0

Based on the description of your goals of allowing for future Enum values and/or classes, a simple solution is to use a delegate dictionary keyed on the base Enum type.

Assume a class declaration like this:

Public Class Class1
    Public Enum WorkDay
         Monday
         Tuesday
         Wednesday
         Thursday
         Friday
    End Enum

    Public Shared Sub Method_Monday()
    End Sub
    Public Shared Sub Method_Tuesday()
    End Sub
    Public Shared Sub Method_Wednesday()
    End Sub
    Public Shared Sub Method_Thursday()
    End Sub
    Public Shared Sub Method_Friday()
    End Sub
End Class

Public Class Class2
    Public Enum NotWorkDay
        Saturday
        Sunday
    End Enum
    Public Shared Sub Method_Saturday()
    End Sub
    Public Shared Sub Method_Sunday()
    End Sub
End Class

Then class (a WinForm in this case) that uses the above classes, would look something like this:

Public Class Form1

    ' declare the delegate dictionary
    Private WorkMethods As New Dictionary(Of [Enum], Action)

    Public Sub New()
        InitializeComponent()
        SetWorkMethods()
    End Sub

    Private Sub SetWorkMethods()
        'fill the dictionary with the needed actions
        WorkMethods.Add(Class1.WorkDay.Monday, New Action(AddressOf Class1.Method_Monday))
        WorkMethods.Add(Class1.WorkDay.Tuesday, New Action(AddressOf Class1.Method_Tuesday))
        WorkMethods.Add(Class1.WorkDay.Wednesday, New Action(AddressOf Class1.Method_Wednesday))
        WorkMethods.Add(Class1.WorkDay.Thursday, New Action(AddressOf Class1.Method_Thursday))
        WorkMethods.Add(Class1.WorkDay.Friday, New Action(AddressOf Class1.Method_Friday))
        WorkMethods.Add(Class2.NotWorkDay.Saturday, New Action(AddressOf Class2.Method_Saturday))
        WorkMethods.Add(Class2.NotWorkDay.Sunday, New Action(AddressOf Class2.Method_Sunday))
    End Sub

    ' a helper method to retrieve and execute the action
    Private Sub DoWork(day As [Enum])
        Dim actionToPerform As Action = Nothing
        If WorkMethods.TryGetValue(day, actionToPerform) Then
            If actionToPerform IsNot Nothing Then actionToPerform()
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        DoWork(Class1.WorkDay.Wednesday)
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        DoWork(Class2.NotWorkDay.Saturday)
    End Sub
End Class

Such usage gives you a lot of flexibility to configure the methods called with out needing to rewrite a Select-Case block when changes are needed. You just add/delete items in the dictionary.

TnTinMn
  • 11,522
  • 3
  • 18
  • 39