Easy way to get all Enum values in c#
Asked Answered
C

5

5

I've tried a little Program... I want to run a program and see all method names in c# class... Here is the code

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

It's work fine, in result I've got this

 adf
 main
 bdf

Now , I want to pass to GetMethods function only one parameter and get result... I don't think it's a good way to pass 5 parameters with 'binary or(|)' ... In BindingFlags Enum is 19 fields and what it will be if I want to pass 18 parameters xD How can I do it passing only one value?

Here Is Enum

 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,
  }
}

I think it's very interesting and helpful question...

Crusted answered 5/8, 2011 at 10:33 Comment(5)
Technically, you didn't ask a question...Hartnett
How can I do it passing only one value?Crusted
You can edit the question and add to it. Better than putting it in a comment.Hartnett
There is no ability. You want to return more than 1 values using only 1 value. Or just write a static method to not repeat this over and over.Farnsworth
I've answered with a method (could easily be generic function) to get a value that is all flags of an enum, you could then subtract values from that if its easier.Filling
S
4

Pay attantion at the body of BindingFlags enumeration, all the values are power of 2. So binary or just calculates sum of provided integer values. In order to pass all flags just send the sum of all int values. In order to pass only some values just send binary integer with 1 in the corresponding position of the flag which needs to be passed. Please see code below.

BindingFlags flag = (BindingFlags)Convert.ToInt32("0000010010000101010", 2)

for your example must be

BindingFlags flag = (BindingFlags)Convert.ToInt32("111110", 2)

and when we print the flag we have a

DeclaredOnly, Instance, Static, Public, NonPublic

and you can get metods

            Type t = typeof(Program);
            MethodInfo[] mi = t.GetMethods(flag);

You right, it is a really interesting question.

Seligman answered 5/8, 2011 at 10:38 Comment(5)
The only issue I see is that of readability - there is no way to tell what flags are actually used without knowing the Enum values.Hartnett
Yes, this is really great way... All I want is this!Crusted
All the answers so far are viable except for this one. It'll work but doing it like this is just asking for trouble down the line. A single misplaced 1 or 0 is all it will take to break stuff, and all just to save a bit of typing.Jacinto
when you have 19 flags, then this saving is not a little bit, and this helps to understanding work with this flagsSeligman
@Artur: Yes, but setting up a few constants for common usages, for example, is going to be more readable and less breakable. I wouldn't know whether to laugh or cry if I saw something like this in production code.Jacinto
F
6

Code below should get a value containing all flags (could easily be made into a generic method), you can then do AllFlags & ~FlagToRemove to get all but one flag.

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"
}
Filling answered 5/8, 2011 at 10:40 Comment(3)
I dont think calling Sum is good idea here. This will fail if you have 'masks' or composite values defined in the enumeration. You probably want a BitwiseOr() in the place of Sum().Alessi
It's not a good way... Imagine that I want to write only 9 of 19 enum values xDCrusted
My imagination isn't that good! In that case go with @Artur's answer, i just gave my answer as it keeps type safty and demonstrates a few different ideas.Filling
S
4

Pay attantion at the body of BindingFlags enumeration, all the values are power of 2. So binary or just calculates sum of provided integer values. In order to pass all flags just send the sum of all int values. In order to pass only some values just send binary integer with 1 in the corresponding position of the flag which needs to be passed. Please see code below.

BindingFlags flag = (BindingFlags)Convert.ToInt32("0000010010000101010", 2)

for your example must be

BindingFlags flag = (BindingFlags)Convert.ToInt32("111110", 2)

and when we print the flag we have a

DeclaredOnly, Instance, Static, Public, NonPublic

and you can get metods

            Type t = typeof(Program);
            MethodInfo[] mi = t.GetMethods(flag);

You right, it is a really interesting question.

Seligman answered 5/8, 2011 at 10:38 Comment(5)
The only issue I see is that of readability - there is no way to tell what flags are actually used without knowing the Enum values.Hartnett
Yes, this is really great way... All I want is this!Crusted
All the answers so far are viable except for this one. It'll work but doing it like this is just asking for trouble down the line. A single misplaced 1 or 0 is all it will take to break stuff, and all just to save a bit of typing.Jacinto
when you have 19 flags, then this saving is not a little bit, and this helps to understanding work with this flagsSeligman
@Artur: Yes, but setting up a few constants for common usages, for example, is going to be more readable and less breakable. I wouldn't know whether to laugh or cry if I saw something like this in production code.Jacinto
F
3

Write static method:

public static class BindingFlagsHelper
{
    public static BindingFlags GetAllMethods()
    {
        return 
            BindingFlags.NonPublic | 
            BindingFlags.DeclaredOnly | 
            BindingFlags.Public | 
            BindingFlags.Instance | BindingFlags.Static;
    }
}
Farnsworth answered 5/8, 2011 at 10:38 Comment(1)
I want easy and short way... Your way is same as mine, I don't see any differences))))Crusted
H
3

You can use a variable to hold the interesting flags and pass that through:

BindingFlags myFlags = BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;

foreach (MethodInfo mInfo in typeof(Program).GetMethods(myFlags))
{
     Console.WriteLine(mInfo.Name);
}
Hartnett answered 5/8, 2011 at 10:40 Comment(0)
M
2

You won't be passing 5 parameters, you'll be passing only one int when the bitwise ors are done executing, you could put unlimited flags and '|' them and only one sizeof(int) parameter will be passed. You could make precomputed values with

const int my_val = flag_1|flag_3|flag_5;

Mumbletypeg answered 5/8, 2011 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.