0

I'm not positive if the title of the thread is accurate.

I have a class of different enums:

public class Enums
{
    public enum StringActions 
    {  
        FIRSTNAME, 
        MIDDLEINITIAL, 
        LASTNAME
    }

    public enum IntegerAction
    {
        RANGE,
        RANDOM
    }
}

I have an object who's constructor, I'd like to take in a generic Enums parameter, which would be capable of accepting either a StringAction or a IntegerAction. I have dictionaries (one for each enum type) that has these enums as the keys, and delegates as values. I want to use the passed in enum to lookup the correct delegate for that enum and then do some work with it.

public class DataPoint
{
    public DataPoint(Enum mAction)
    {
        if (mAction == Enums.StringAction)
        { 
             var act = StringActionDictionary[mAction];
        }
        else if (mAction == Enums.IntegerAction)
        {
             var act = IntegerActionDictionary[mAction];
        }
        ...
    }
 }

With this implementation, I'll need to cast 'mAction' to the correct type but how can that be accomplished at runtime? Is reflection an option here, or is there another way?

Talen Kylon
  • 1,908
  • 7
  • 32
  • 60
  • 1
    `if(mAction is Enums.StringAction)` – Mathias R. Jessen May 13 '17 at 02:27
  • 1
    What is the point of this? Why don't you just have an overload of `DataPoint()` for each type? That way, you don't need to check the type at runtime; the compiler does all the heavy lifting. If that doesn't work in your case, you need to be more clear about that. Provide a good [mcve] that shows clearly the context and any constraints, and explain precisely what you've tried and what specifically you're having trouble with. – Peter Duniho May 13 '17 at 03:22
  • 1
    If possible, method overload would be preferred (your one answerer below even agrees enough to have updated their answer to reflect that). The marked duplicate shows that approach, along with many others. IMHO, the option using `dynamic` would be the next preferable to a straight overload; it still uses overloads, which you'd have to also declare, but the overload resolution would be handled at runtime instead of compile time. If neither of those work in your case, there are plenty of other options to choose from. – Peter Duniho May 13 '17 at 04:25

1 Answers1

1

It would make more sense to just provide two constructors, each taking a different enum. This will make your code more intentional and easier to understand for consumers:

public class DataPoint
{
    public DataPoint(Enums.StringAction mAction)
    {
        DoSomeWorkWithStringAction(mAction);                        
    }
    public DataPoint(Enums.IntegerAction mAction)
    {
        DoSomeWorkWithIntegerAction(mAction);
    }

    // Rest of class omitted

If, however you really want to provide the generic implementation, you can use the is keyword to check the type of Enum passed in, and then cast it to the appropriate type inside the if block so you can use it. Just recognize that this constructor will accept any old Enum, including ones you don't have conditions for.

For example:

public class DataPoint
{
    public DataPoint(Enum mAction)
    {
        if (mAction is Enums.StringAction)
        {
            DoSomeWorkWithStringAction((Enums.StringAction)mAction);
        }
        else if (mAction is Enums.IntegerAction)
        {
            DoSomeWorkWithIntegerAction((Enums.IntegerAction)mAction);
        }
    }

    private void DoSomeWorkWithIntegerAction(Enums.IntegerAction actionToTake)
    {
        Console.WriteLine($"Enum was an IntegerAction, with action: {actionToTake}");
    }

    private void DoSomeWorkWithStringAction(Enums.StringAction actionToTake)
    {
        Console.WriteLine($"Enum was a StringAction, with action: {actionToTake}");
    }
}

In either case, the instantiation of the class looks the same:

static void Main()
{
    var intDp = new DataPoint(Enums.IntegerAction.RANGE);
    var strDp = new DataPoint(Enums.StringAction.FIRSTNAME);

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

As does the output:

enter image description here

Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • Thank you for opening up my eyes. I don't know why the idea of an overloaded constructor didn't come to me initially. – Talen Kylon May 13 '17 at 13:29