BindingFlags - 获取所有这些(最大成员数)

T.T*_*dua 5 c# reflection

我试图获得所有类型的 BindingFlags(为了获得所有属性):

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 ;
Run Code Online (Sandbox Code Playgroud)

但是,这将返回空集合:

obj.GetType().GetProperties( ALL_BF ); 
Run Code Online (Sandbox Code Playgroud)

当我尝试:

obj.GetType().GetProperties( BindingFlags.Public );
Run Code Online (Sandbox Code Playgroud)

返回了许多成员。

1 有人可以解释为什么第一种方法没有返回结果吗?哪一个会干扰另一个?

2)我应该使用哪种组合来获得所有(可获得的)成员?

Ser*_*eye 5

你应该试试这个:

//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));
Run Code Online (Sandbox Code Playgroud)

如您所见,情况不一样。原因是 BindingFlags “过滤器”会显式和隐式地产生结果(如果是,则反转)。也就是说,如果您想要最大成员数,您应该传递一些基本的包含性“请求”BindingFlags,如 Public 和 Instance,并避免像 DeclaredOnly(不包括继承的成员)这样的独占性“postfilter”BindingFlags。

解释:

结合标志,所以你很可能需要没有他们。我猜你会想到:

GetMembers(); //Simple way described in MSDN but just syntactically equivalent
Run Code Online (Sandbox Code Playgroud)

但!不幸的是,无参数版本由于某种原因只返回公共成员。然后,假设您无论如何都需要传递绑定标志(在变量等中),您可能需要:

GetMembers((BindingFlags)0); //but it's like passing BindingFlags.Default
Run Code Online (Sandbox Code Playgroud)

不是很明显,但 0 表示“无”(即 BindingFlags.Default),而不是零 BindingFlags。然后呢?也许:

GetMembers((BindingFlags)(-1));
Run Code Online (Sandbox Code Playgroud)

然后你突然得到了所有的 BindingFlags!但不是所有成员(可能根本没有),因为他们被绑定了

显然,BindingFlags 像可切换过滤器一样工作:如果未指定,则反之(例如,从最终结果中丢弃相应的成员)。所以最后,你需要传递其中最通用的。这对于大多数用途就足够了:

GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
//or
GetMembers((BindingFlags)60); //just a sum of int representations of these flags
Run Code Online (Sandbox Code Playgroud)

为什么 -1 返回所有标志?


您需要使用,-1因为它的二进制表示是...11111111(例如 -2...11111110等),这意味着它的所有位都是“真”。这与对每个常量使用按位或(按位运算)是一样的BindingFlags。您可以使用以下方法亲自查看:

Console.WriteLine(Convert.ToString(-1, 2)); //-1 is the converted value(can be variable); 2 means converting to binary

在此之后,您只需要将结果值转换为BindingFlagsas GetMembers-like 方法只接受这种类型。