How to call a method with an enumerated (enum) argument through reflection?
Asked Answered
G

2

5

I have to call the following method:

public bool Push(button RemoteButtons)

RemoteButtons is defined this way:

enum RemoteButtons { Play, Pause, Stop }

The Push method belongs to the RemoteControl class. Both the RemoteControl class and the RemoteButton enumeration are located inside an assembly that I need to load at runtime. I'm able to load the assembly and create an instance of RemoteControl this way:

Assembly asm = Assembly.LoadFrom(dllPath);
Type remoteControlType = asm.GetType("RemoteControl");
object remote = Activator.CreateInstance(remoteControlType);

Now, how do I call the Push method knowing that it's sole argument is an enum that I also need to load at runtime?

If I was on C# 4, I would use a dynamic object but I'm on C# 3/.NET 3.5 so it's not available.

Gripper answered 14/3, 2014 at 22:54 Comment(5)
Even in C#4, I wouldn't use dynamic for this.Cayla
What do you mean "unknown" enum?Trinary
I think the OP means: enum RemoteButtons { Play, Pause, Stop } ...if this is correct, the OP needs to make this clear. :)Cayla
I would have an interface - e.g. IRemoteControl - which exposes bool Push(...) and referenced by the class instantiating via reflection and implemented by RemoteControl. Then you don't have to call the method via reflection.Cayla
Edited for the sake of clarity.Gripper
P
6

Assuming I have the following structure:

public enum RemoteButtons
{
    Play,
    Pause,
    Stop
}
public class RemoteControl
{
    public bool Push(RemoteButtons button)
    {
        Console.WriteLine(button.ToString());
        return true;
    }
}

Then I can use reflection to get at the values like so:

Assembly asm = Assembly.GetExecutingAssembly();
Type remoteControlType = asm.GetType("WindowsFormsApplication1.RemoteControl");
object remote = Activator.CreateInstance(remoteControlType);

var methodInfo = remoteControlType.GetMethod("Push");
var remoteButtons = methodInfo.GetParameters()[0];

// .Net 4.0    
// var enumVals = remoteButtons.ParameterType.GetEnumValues();

// .Net 3.5
var enumVals = Enum.GetValues(remoteButtons.ParameterType);

methodInfo.Invoke(remote, new object[] { enumVals.GetValue(0) });   //Play
methodInfo.Invoke(remote, new object[] { enumVals.GetValue(1) }); //Pause
methodInfo.Invoke(remote, new object[] { enumVals.GetValue(2) }); //Stop

I am getting the parameter type from the method and then getting the enum values from that type.

Piranha answered 15/3, 2014 at 3:8 Comment(2)
Unfortunately, it seems like GetEnumValues is only available with .NET 4+. I'm on 3.5.Gripper
I'm accepting this answer since it provided 95% of what I needed. I just made a small edit so the code will work with .NET 3.5.Gripper
E
1

The follow code can work right!

asm = Assembly.LoadFrom(dllPath);
Type typeClass = asm.GetType("RemoteControl");
obj = System.Activator.CreateInstance(typeClass);
Type[] types = asm.GetTypes();
Type TEnum = types.Where(d => d.Name == "RemoteButtons").FirstOrDefault();
MethodInfo method = typeClass.GetMethod("Push", new Type[] { TEnum});
object[] parameters = new object[] { RemoteButtons.Play };
method.Invoke(obj, parameters);

Pay attention to this code:“Type TEnum = types.Where(d => d.Name == "RemoteButtons").FirstOrDefault();” you must get the Type from the Assembly use this code.

but not Directly use typeof(RemoteButtons) to find the method like this:"MethodInfo method = typeClass.GetMethod("Push", new Type[] { typeof(RemoteButtons) });" This is not Actually the SAME Type .

Episternum answered 28/6, 2018 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.