BindingFlags说明

本文详细介绍了BindingFlags枚举的各个标志及其用途,包括如何通过这些标志来定位特定类型的成员(如公共或私有成员),以及如何调用不同类型的成员(如构造函数、方法等)。同时还解释了如何使用这些标志来定制搜索行为。
为了获取返回值,必须指定 BindingFlags.Instance 或 BindingFlags.Static。

指定 BindingFlags.Public 可在搜索中包含公共成员。

指定 BindingFlags.NonPublic 可在搜索中包含非公共成员(即私有成员和受保护的成员)。

指定 BindingFlags.FlattenHierarchy 可包含层次结构上的静态成员。

下列 BindingFlags 修饰符标志可用于更改搜索的执行方式:

BindingFlags.IgnoreCase,表示忽略 name 的大小写。

BindingFlags.DeclaredOnly,仅搜索 Type 上声明的成员,而不搜索被简单继承的成员。

可以使用下列 BindingFlags 调用标志表示要对成员采取的操作:

CreateInstance,表示调用构造函数。忽略 name。对其他调用标志无效。

InvokeMethod,表示调用方法,而不调用构造函数或类型初始值设定项。对 SetField 或 SetProperty 无效。

GetField,表示获取字段值。对 SetField 无效。

SetField,表示设置字段值。对 GetField 无效。

GetProperty,表示获取属性。对 SetProperty 无效。

SetProperty 表示设置属性。对 GetProperty 无效。

 

BindingFlags.Instance                     : 对象实例
BindingFlags.Static                          : 静态成员
BindingFlags.Public                         : 指可在搜索中包含公共成员
BindingFlags.NonPublic                 : 指可在搜索中包含非公共成员(即私有成员和受保护的成员)
BindingFlags.FlattenHierarchy      : 指可包含层次结构上的静态成员
BindingFlags.IgnoreCase               : 表示忽略 name 的大小写
BindingFlags.DeclaredOnly           : 仅搜索 Type 上声明的成员,而不搜索被简单继承的成员
BindingFlags.CreateInstance        : 表示调用构造函数。忽略 name。对其他调用标志无效

<think>我们正在讨论C#中的BindingFlags.Instance枚举值。根据引用[1]和[2],BindingFlags用于指定反射搜索成员的条件。BindingFlags.Instance表示我们要搜索实例成员(非静态成员)。 ### 作用 - **BindingFlags.Instance**:指定反射操作应包含实例成员(即非静态成员),如实例字段、实例属性、实例方法和实例构造函数等。 ### 使用场景 当使用反射获取类型成员(如方法、属性、字段、构造函数等)时,默认情况下,许多反射方法(如`Type.GetMethods()`)只返回公共实例成员(相当于`BindingFlags.Public | BindingFlags.Instance`)。如果我们还需要获取非公共实例成员,或者同时获取静态成员,就需要显式指定BindingFlags组合。 ### 示例 #### 1. 获取所有实例方法(包括公共和非公共) ```csharp using System; using System.Reflection; public class MyClass { public void PublicMethod() { } private void PrivateMethod() { } public static void StaticMethod() { } } class Program { static void Main() { Type type = typeof(MyClass); // 获取所有实例方法(包括公共和非公共),但不包括静态方法 MethodInfo[] methods = type.GetMethods( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); foreach (var method in methods) { Console.WriteLine(method.Name); } } } ``` 输出可能包括: ``` PublicMethod PrivateMethod ``` 注意:这里不会输出`StaticMethod`,因为我们没有指定`BindingFlags.Static`。 #### 2. 获取实例构造函数 ```csharp // 获取所有实例构造函数(包括公共和非公共) ConstructorInfo[] constructors = type.GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); ``` #### 3. 获取实例字段 ```csharp // 获取所有实例字段(包括公共和非公共) FieldInfo[] fields = type.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); ``` ### 重要说明 - 当使用BindingFlags时,通常需要组合多个标志。例如,要同时获取公共和非公共的实例成员,需要组合`BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic`。 - 如果不指定`BindingFlags.Public`,则不会返回公共成员;同样,如果不指定`BindingFlags.NonPublic`,则不会返回非公共成员(私有、受保护等)。 - 默认情况下,如果只指定`BindingFlags.Instance`而不指定`BindingFlags.Public`或`BindingFlags.NonPublic`,则可能不会返回任何成员(具体行为取决于API,通常需要显式指定公开或非公开)。 ### 与静态成员的区别 - 如果要获取静态成员,应使用`BindingFlags.Static`。 - 实例成员和静态成员可以同时获取,例如: ```csharp // 获取所有实例和静态的公共方法 MethodInfo[] allMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); ``` ### 在构造函数中的应用 在用户之前的问题中,获取构造函数的代码: ```csharp var t = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.Public); ``` 这表示获取类型T的所有公共实例构造函数(即非静态的公共构造函数)。注意,构造函数总是实例成员(因为静态构造函数不能这样获取),所以这里`BindingFlags.Instance`是必要的吗?实际上,在构造函数中,`BindingFlags.Instance`是默认包含的,但显式指定可以更清晰,并且当需要同时获取非公共构造函数时,可以添加`BindingFlags.NonPublic`。 ### 总结 - **BindingFlags.Instance** 用于指定反射操作应包含实例成员。 - 通常需要与其他标志(如`Public`、`NonPublic`)组合使用,以精确控制返回的成员类型。 - 在获取构造函数、方法、属性、字段等时,都可以使用此标志。 [^1][^2] §§相关问题§§ 1. BindingFlags.Static 和 BindingFlags.Instance 有什么区别? 2. 如何通过反射获取私有实例方法? 3. 在C#反射中,如何同时获取静态和实例成员?</think>### C# BindingFlags.Instance 详解 #### 作用解析 `BindingFlags.Instance` 是 C# 反射系统中的关键枚举值,用于**指定只检索实例成员**(非静态成员)。它的核心作用包括: 1. **筛选实例成员**:排除静态成员,只获取与对象实例关联的成员[^1][^2] 2. **组合控制**:通常与其他 BindingFlags 组合使用(如 Public/NonPublic),精确控制反射范围 3. **性能优化**:缩小反射搜索范围,提高效率 #### 典型应用场景 1. **获取实例构造函数** ```csharp // 获取所有公共实例构造函数 ConstructorInfo[] publicCtors = typeof(MyClass) .GetConstructors(BindingFlags.Instance | BindingFlags.Public); // 获取所有实例构造函数(含私有) ConstructorInfo[] allCtors = typeof(MyClass) .GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ``` 2. **访问实例方法** ```csharp // 获取所有实例方法(含私有) MethodInfo[] methods = typeof(MyClass) .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ``` 3. **操作实例字段** ```csharp // 获取私有实例字段值 FieldInfo field = typeof(MyClass) .GetField("_privateField", BindingFlags.Instance | BindingFlags.NonPublic); object value = field.GetValue(myInstance); ``` #### 组合使用示例 ```csharp public class Sample { private int _counter; // 实例字段 public Sample() {} // 公共实例构造函数 private void Increment() { _counter++; } // 私有实例方法 } // 反射操作 var type = typeof(Sample); // 获取所有实例成员(字段+方法+构造器) MemberInfo[] allInstanceMembers = type.GetMembers( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); // 创建实例(使用实例构造函数) object instance = Activator.CreateInstance(type); // 调用私有实例方法 MethodInfo increment = type.GetMethod("Increment", BindingFlags.Instance | BindingFlags.NonPublic); increment.Invoke(instance, null); ``` #### 关键注意事项 1. **必须组合使用**:单独使用 `BindingFlags.Instance` 通常无效,需搭配 `Public/NonPublic` ```csharp // 错误用法(可能返回空) var wrong = type.GetMethods(BindingFlags.Instance); // 正确用法 var correct = type.GetMethods(BindingFlags.Instance | BindingFlags.Public); ``` 2. **与静态成员对比**: ```csharp // 实例成员(需要对象实例) var instanceMember = type.GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public); // 静态成员(不需要对象实例) var staticMember = type.GetMethod("StaticMethod", BindingFlags.Static | BindingFlags.Public); ``` 3. **性能建议**:对频繁调用的反射操作,考虑缓存结果(如缓存 MethodInfo 对象) [^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值