如何通过反射优雅获取.NET类型的全部成员?
嘿,这个问题我太熟了!首先得纠正一个小误区:你之前加的一大堆BindingFlags里,很多其实是用于调用成员(比如Invoke方法)的标志,根本不影响GetMembers获取成员的结果,属于冗余配置。
默认的type.GetMembers()只返回公共的实例和静态成员,而且不会包含继承来的非公共成员,所以才只有19个。要获取全部成员,你只需要组合成员筛选类的BindingFlags就行,完全不用写那么长一串。
简洁的正确写法
要获取某类型的所有成员(公共+非公共、实例+静态,包括继承自父类的成员),只需要这几个标志组合:
var type = typeof(int); var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy; var members = type.GetMembers(flags); for (var i = 0; i < members.Length; i++) Console.WriteLine($"{i, 2} {members[i]}");
这样跑出来的成员数量和你之前全加标志的结果一致(34个),但代码简洁太多了。
各标志的作用
Public | NonPublic:覆盖所有访问级别的成员Instance | Static:同时包含实例成员和静态成员FlattenHierarchy:包含继承层次中的公共/受保护静态成员(对于值类型来说,会包含从ValueType和Object继承来的相关静态成员)
额外需求:只获取当前类型声明的成员
如果你不想包含继承来的成员,把BindingFlags.DeclaredOnly加上,去掉FlattenHierarchy即可:
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
本质上就是区分清楚BindingFlags的两类用途:一类是筛选要获取的成员范围,另一类是控制成员的调用行为——获取成员时只需要前者,后者加了也是白加~
内容的提问来源于stack exchange,提问作者user11551794
相关产品推荐
相关产品推荐

