2
class Program
{
    static void Main(string[] args)
    {
        Type[] types = Assembly.GetExecutingAssembly().GetTypes();

        Type TEnum = types.Where(d => d.Name == "TEnum").FirstOrDefault();
        var values = TEnum.GetEnumValues();
        var error = new object();
        foreach (var value in values)
        {
            if (value.ToString() == "Test2")
            {
                error = value;

            }
        }

        TestMethod("A",ref error);
    }

    public static void TestMethod(string a, ref TEnum b)
    {

    }

    public enum TEnum
    {
        Test, 
        Test2
    }

}

In the above code I am trying to pass enum which I got from refection. This is just a sample code actually the TestMethod(string a, ref TEnum b) and enum TEnum are in different assembly which I am loading through Reflection. In this sample how I can pass enum as parameter to method. Currently I am getting compilation error for this.

Thanks in advance

Anup
  • 39
  • 11

3 Answers3

2

You need to make changes to your test method so that it accepts more generalized type something called object.

But In your case looking at comments it seems you can not change the signature of method. You have another alternative of using reflection. Be aware it cost more than regular calling (call from referenced assembly in project).

Call the Test method using reflection like this.

using System;
using System.Linq;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        Program p = new Program();
        Type[] types = Assembly.GetExecutingAssembly().GetTypes();
        Type TEnum = types.Where(d => d.Name == "TEnum").FirstOrDefault();
        var values = TEnum.GetEnumValues();
        var error = new object ();
        foreach (var value in values)
        {
            if (value.ToString() == "Test2")
            {
                error = value;
            }
        }

        var program = Assembly.GetExecutingAssembly().GetTypes().First(d => d.Name == "Program");
        foreach (var method in program.GetMethods())
        {
            if (method.Name == "TestMethod")
            {
                method.Invoke(null, new object[2] // may need to pass instance in case of instance method.
                {
                "A", error
                }

                );
            }
        }
    }

    public static void TestMethod(string a, ref TEnum b)
    {
        Console.WriteLine("test");
    }
}

public enum TEnum
{
    Test,
    Test2
}

Click here to view dotnet fiddle.

Jenish Rabadiya
  • 6,708
  • 6
  • 33
  • 62
1

You can use reflection to fetch the method from its type and invoke it.

       var args = new[] { "A", error };
        parentType.GetMethod("TestMethod").Invoke(null, "A",args);
        error = args[1];
Victor Mukherjee
  • 10,487
  • 16
  • 54
  • 97
  • Hi Victor, Your approach seems to work. Now one question the enum is passed as ref how can I acheive this using reflection? – Anup May 13 '15 at 06:43
  • Thanks Victor, I got the ref parameter in your solution too. – Anup May 13 '15 at 06:50
0

You need to convert value to the enum representation by using Enum.Parse.

Eg.

if (value.ToString() == "Test2")
{
    var testEnum = (TEnum)Enum.Parse(typeof(TEnum), value);
}

You should then be able to pass testEnum to your TestMethod.

EDIT:

Since you said you don't have direct access to TEnum, you could try Convert.ChangeType (see this answer for more: Setting a property by reflection with a string value).

Eg.

Type tEnum = types.Where(d => d.Name == "TEnum").FirstOrDefault();

if (value.ToString() == "Test2")
{
    object testEnum = Enum.Parse(tEnum.GetType(), value);
    var testEnumType = Convert.ChangeType(testEnum, tEnum.GetType());
}
Community
  • 1
  • 1
Steve
  • 9,335
  • 10
  • 49
  • 81
  • 1
    I cant typecast since TEnum is in different assembly. I can get the type of it using reflection but how to typecast with a type after getting type from reflection? – Anup May 13 '15 at 05:37
  • Hi Steve, I tried with your approach, still compiler is throwing error when I am passing testEnumType to TestMethod – Anup May 13 '15 at 05:53
  • @Anup, can you add the exception details to your question? – Silvermind May 13 '15 at 05:57
  • The best overloaded method match for TestMethod(string, TEnum) has some invalid arguments – Anup May 13 '15 at 05:57
  • If you're TestMethod is in a different assembly to the enum, then you can't have the enum type as a parameter. The parameter type will have to be object, then you can use reflection to get the value. – Steve May 13 '15 at 06:02
  • Unfortunately the assembly I am using is not in my control, so I can't make any changes to methods in that assembly. – Anup May 13 '15 at 06:06
  • Can you just add a reference to the assembly in Visual Studio? – Steve May 13 '15 at 06:08
  • 1
    The TestMethod assembly has a reference to the enum assembly. How can you call the TestMethod from your assembly, without having a reference to the assembly having the enum type? – Victor Mukherjee May 13 '15 at 06:18
  • @Anup Get the method through reflection too. A dirty hack can be to make your object a dynamic type, ugh. It is better to use reflection to get the method, but you can at least tell if you got the first stuff right by using the dynamic 'option'. – Silvermind May 13 '15 at 06:18
  • @VictorMukherjee is right, but since the method has a parameter called TEnum, we can almost assume the actual method is generic, otherwise conventions look violated. I think the real method could be `public static void TestMethod(string a, ref TEnum b)` – Silvermind May 13 '15 at 06:20
  • @Steve I can't add reference to assembly in Visual Studio – Anup May 13 '15 at 06:24
  • @Anup, without using something like Jenish's answer, that may be the only way. Is there a reason you can't reference it? – Steve May 13 '15 at 06:25
  • @Silvermind I tried changing type from var to dynamic but still its not solving the problem. dynamic testEnumType = Convert.ChangeType(testEnum, tEnum.GetType()); TestMethod("A", ref testEnumType); – Anup May 13 '15 at 06:27
  • @Anup stating dynamic is required in method signature not while passing parameter. alternatively dynamic is type that will try to cast to your enum type which will fail. The only way I can see is change of method signature. – Jenish Rabadiya May 13 '15 at 06:31