【问题标题】:How to pass enum value to method through reflection如何通过反射将枚举值传递给方法
【发布时间】:2015-05-13 05:30:06
【问题描述】:
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
    }

}

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

提前致谢

【问题讨论】:

    标签: c# .net c#-4.0 reflection enums


    【解决方案1】:

    您需要对您的测试方法进行更改,以便它接受更通用的类型,称为对象。

    但是在您查看 cmets 的情况下,您似乎无法更改方法的签名。您还有另一种使用反射的方法。请注意,它比常规调用(从项目中引用的程序集调用)花费更多。

    像这样使用反射调用 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
    }
    

    点击here查看dotnet fiddle。

    【讨论】:

      【解决方案2】:

      您可以使用反射从其类型中获取方法并调用它。

             var args = new[] { "A", error };
              parentType.GetMethod("TestMethod").Invoke(null, "A",args);
              error = args[1];
      

      【讨论】:

      • 嗨,维克多,你的方法似乎奏效了。现在有一个问题,枚举作为 ref 传递我如何使用反射来实现这一点?
      • 谢谢 Victor,我在你的解决方案中也得到了 ref 参数。
      【解决方案3】:

      您需要使用Enum.Parse 将值转换为枚举表示。

      例如。

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

      然后您应该能够将 testEnum 传递给您的 TestMethod。

      编辑:

      既然你说你不能直接访问 TEnum,你可以试试 Convert.ChangeType(更多信息请看这个答案:Setting a property by reflection with a string value)。

      例如。

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

      【讨论】:

      • 我无法进行类型转换,因为 TEnum 在不同的程序集中。我可以使用反射来获取它的类型,但是在从反射中获取类型后如何使用类型进行类型转换?
      • 嗨史蒂夫,我尝试了你的方法,当我将 testEnumType 传递给 TestMethod 时,编译器仍然抛出错误
      • @Anup,您可以在您的问题中添加异常详细信息吗?
      • TestMethod(string, TEnum) 的最佳重载方法匹配有一些无效参数
      • TestMethod 程序集有对枚举程序集的引用。如何在不引用具有枚举类型的程序集的情况下从程序集中调用 TestMethod?
      猜你喜欢
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      相关资源
      最近更新 更多