Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 881
ChrisB Avatar asked Mar 14 '14 22:03

ChrisB


People also ask

How do you pass an enum as an argument?

enums are technically descendants of Enum class. So, if you want to use only Enum's standard methods in your method (such as values()), pass the parameter like this: static void printEnumValue(Enum generalInformation) See, that the only thing you have to change is the capital letter E.

How to Get values from an enum?

To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.

Can you add methods to enum?

You can use extension methods to add functionality specific to a particular enum type.


2 Answers

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.

like image 159
John Koerner Avatar answered Oct 10 '22 02:10

John Koerner


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 .

like image 38
pduan Avatar answered Oct 10 '22 01:10

pduan