I tried to get all kind of BindingFlags (in order to get all properties):
BindingFlags ALL_BF = BindingFlags.CreateInstance | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding | BindingFlags.FlattenHierarchy | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.IgnoreCase | BindingFlags.IgnoreReturn | BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.OptionalParamBinding | BindingFlags.Public | BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty | BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.Static | BindingFlags.SuppressChangeType ;
however, this returns empty collection:
obj.GetType().GetProperties( ALL_BF );
when I tried:
obj.GetType().GetProperties( BindingFlags.Public );
that returned many members.
1 Can someone explain why first method didnt return result? Which one interferes with other one?
2) Which combination I should use, to get ALL (obtainable) members?
You should try this:
//All actual properties:
obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
//or
obj.GetType().GetProperties((BindingFlags)60);
//All binding flags (if really needed):
obj.GetType().GetProperties((BindingFlags)(-1));
As you can see, it's not the same. The reason is that the BindingFlags "filters" result both explicitly and implicitly (inverted if so). That said, if you want maximum members you should pass some basic inclusive "request" BindingFlags like Public and Instance and avoid exclusive "postfilter" BindingFlags like DeclaredOnly (excludes inherited members).
It's binding flags, so you most likely need none of them. I guess you think of:
GetMembers(); //Simple way described in MSDN but just syntactically equivalent
BUT! Unfortunately, parameterless version returns only public members for some reason. Then, assuming you need to pass binding flags anyway (in variable, etc.), you'll probably want:
GetMembers((BindingFlags)0); //but it's like passing BindingFlags.Default
Not so obvious, but 0 means "Nothing" (which is BindingFlags.Default), not zero BindingFlags. Then what? Maybe:
GetMembers((BindingFlags)(-1));
Then you suddenly got all the BindingFlags! But not all the members (probably none at all), because they were bound.
Apparently, BindingFlags works like switchable filters: if not specified, it's vice versa (e.g. corresponding members are discarded from the end result). So finally, you need to pass most generic of them. This will be enough for most purposes:
GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
//or
GetMembers((BindingFlags)60); //just a sum of int representations of these flags
Why -1 returns all the flags?
You need to use
-1
because its binary representation is...11111111
(for example -2 is...11111110
etc.), which means that all of its bits are "true". This is the same like using bitwise OR (Bitwise operations) with everyBindingFlags
constant. You can see it for yourself by using:
Console.WriteLine(Convert.ToString(-1, 2)); //-1 is the converted value(can be variable); 2 means converting to binary
After this you only need to convert the resulted value to
BindingFlags
asGetMembers
-like methods accept only this type.
The combination of
BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
used in GetProperties(...)
should be enough.
You may want to add BindingFlags.DeclaredOnly
depending on your use-case.
(For fast debugging I use ((BindingFlags)62)
to create the mentioned combination.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With