在C#中获取所有枚举值的简单方法

5

我尝试过一个小程序... 我想运行一个程序并查看c#类中的所有方法名称... 下面是代码:

class Program
{
    public int adf()
    {
        return 0;
    }
    static void Main(string[] args)
    {

        foreach (MethodInfo mInfo in typeof(Program).GetMethods(BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
        {
            Console.WriteLine(mInfo.Name);
        }
       Console.ReadKey();
    }
    private void bdf()
    {
        Console.WriteLine("Dg");
    }
}

它运行良好,结果我得到了这个。

 adf
 main
 bdf

现在,我想只传递一个参数并获取结果给GetMethods函数...使用“二进制或(|)”传递5个参数并不是一个好的方式... BindingFlags枚举中有19个字段,如果我想传递18个参数会怎么样xD。我该如何只传递一个值呢?
这里是枚举:
 public enum BindingFlags
{
    Default = 0,
    IgnoreCase = 1,
    DeclaredOnly = 2,
    Instance = 4,
    Static = 8,
    Public = 16,
    NonPublic = 32,
    FlattenHierarchy = 64,
    InvokeMethod = 256,
    CreateInstance = 512,
    GetField = 1024,
    SetField = 2048,
    GetProperty = 4096,
    SetProperty = 8192,
    PutDispProperty = 16384,
    PutRefDispProperty = 32768,
    ExactBinding = 65536,
    SuppressChangeType = 131072,
    OptionalParamBinding = 262144,
    IgnoreReturn = 16777216,
  }
}

我认为这是一个非常有趣和有用的问题...


6
从技术上讲,您没有提出问题... - Oded
我该如何传递仅一个值? - Chuck Norris
1
你可以编辑问题并添加内容,这比放在评论中更好。 - Oded
没有这种能力。你想要仅使用一个值返回多个值。或者编写一个静态方法,以免重复这个过程。 - Sergey Metlov
1
我已经用一种方法(可以很容易地成为通用函数)来获取枚举的所有标志值,并且您可以从中减去值,如果这更容易的话。 - George Duckett
5个回答

6

以下代码应该可以获得一个包含所有标志的值(可以很容易地转换成通用方法),然后您可以执行 AllFlags &~ FlagToRemove 来获取除一个标志外的所有标志。

AllFlags = (EnumFlagType)Enum.GetValues(typeof(EnumFlagType))
                             .Cast<int>().Aggregate((acc, next) => acc | next);

[Flags]
enum TestEnum { one = 1, two = 2, three = 4, four = 8 };

void Main()
{

    var AllFlags = (TestEnum)Enum.GetValues(typeof(TestEnum))
                             .Cast<int>().Aggregate((acc, next) => acc | next);

    Console.WriteLine(AllFlags); // Prints "one, two, three, four"

    Console.WriteLine(AllFlags & ~two); // Prints "one, three, four"
}

2
我认为在这里调用 Sum 不是一个好主意。如果枚举中定义了“掩码”或复合值,这将失败。你可能想要在 Sum() 的位置使用 BitwiseOr() - leppie
这不是一个好的方式... 想象一下,我只想写19个枚举值中的9个 xD - Chuck Norris
1
我的想象力不是那么好!在这种情况下,就按照@Artur的答案来吧,我只是给出了我的答案,因为它保持了类型安全并展示了一些不同的想法。 - George Duckett

4
请注意BindingFlags枚举的主体部分,所有值都是2的幂。因此,二进制或只计算提供的整数值的总和。为了传递所有标志,只需发送所有int值的总和。为了仅传递某些值,请发送具有相应标志位置中为1的二进制整数。请参见下面的代码。
BindingFlags flag = (BindingFlags)Convert.ToInt32("0000010010000101010", 2)

你的示例必须是这样的:
BindingFlags flag = (BindingFlags)Convert.ToInt32("111110", 2)

当我们打印flag时,我们得到一个

DeclaredOnly, Instance, Static, Public, NonPublic

你可以获取方法。
            Type t = typeof(Program);
            MethodInfo[] mi = t.GetMethods(flag);

你说得没错,这是一个非常有趣的问题。

我唯一看到的问题是可读性 - 如果不知道枚举值,就无法确定实际使用了哪些标志。 - Oded
是的,这确实是一个很棒的方式...我想要的就是这个! - Chuck Norris
1
到目前为止,所有的答案都是可行的,除了这一个。它可以工作,但像这样做只会在以后引起麻烦。一个单独错放的 10 就足以打乱一切,而这一切只是为了节省一点打字工夫。 - LukeH
1
当您拥有19个标志时,这种节省不是一点点,这有助于理解如何使用这些标志进行工作。 - Artur Keyan
1
@Artur:是的,但是为常见用途设置一些常量会更易读、更不容易出错。如果我看到生产代码中有这样的东西,我不知道是笑还是哭。 - LukeH

3

编写静态方法:

public static class BindingFlagsHelper
{
    public static BindingFlags GetAllMethods()
    {
        return 
            BindingFlags.NonPublic | 
            BindingFlags.DeclaredOnly | 
            BindingFlags.Public | 
            BindingFlags.Instance | BindingFlags.Static;
    }
}

1
我想要一种简单而短的方式...你的方式和我的一样,我看不出任何区别)))) - Chuck Norris

3
你可以使用一个变量来保存感兴趣的标志,并将其传递:
BindingFlags myFlags = BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;

foreach (MethodInfo mInfo in typeof(Program).GetMethods(myFlags))
{
     Console.WriteLine(mInfo.Name);
}

2

您不会传递5个参数,而只会在执行“按位或”时传递一个int,您可以放置无限的标志并使用'|'进行标志,只会传递一个sizeof(int)参数。 您可以使用以下代码创建预计算值:

const int my_val = flag_1|flag_3|flag_5;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接