如何通过反射将枚举值传递给方法

时间:2023-01-26 14:28:45
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.

在上面的代码中,我试图通过我从refection得到的枚举。这只是一个示例代码,实际上TestMethod(字符串a,ref TEnum b)和枚举TEnum在不同的程序集中,我通过Reflection加载。在此示例中,我如何将枚举作为参数传递给方法。目前我收到编译错误。

Thanks in advance

提前致谢

3 个解决方案

#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];

#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.

使用这样的反射调用Test方法。

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.

点击这里查看dotnet小提琴。

#3


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

您需要使用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.

然后,您应该能够将testEnum传递给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).

既然你说你没有直接访问TEnum,你可以试试Convert.ChangeType(更多信息请参见这个答案:通过反射用字符串值设置属性)。

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());
}

#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];

#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.

使用这样的反射调用Test方法。

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.

点击这里查看dotnet小提琴。

#3


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

您需要使用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.

然后,您应该能够将testEnum传递给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).

既然你说你没有直接访问TEnum,你可以试试Convert.ChangeType(更多信息请参见这个答案:通过反射用字符串值设置属性)。

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());
}