转 Type.InvokeMember 方法 (String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[])
转自 http://www.xuebuyuan.com/1196545.html
当在派生类中重写时,使用指定的绑定约束并匹配指定的参数列表、修饰符和区域性,调用指定成员。
命名空间:System
程序集:mscorlib(在 mscorlib.dll 中)
public abstract Object InvokeMember ( string name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters )
参数
- name
-
String,它包含要调用的构造函数、方法、属性或字段成员的名称。
- 或 -
空字符串 (""),表示调用默认成员。
- 或 -
对于 IDispatch 成员,则为一个表示 DispID 的字符串,例如“[DispID=3]”。
- invokeAttr
-
一个位屏蔽,由一个或多个指定搜索执行方式的 BindingFlags 组成。访问可以是 BindingFlags 之一,如Public、NonPublic、Private、InvokeMethod 和 GetField 等。不需要指定查找类型。如果省略查找类型,则将应用BindingFlags.Public |BindingFlags.Instance。
- binder
-
一个 Binder 对象,该对象定义一组属性并启用绑定,而绑定可能涉及选择重载方法、强制参数类型和通过反射调用成员。
- 或 -
若为 空引用(在 Visual Basic 中为 Nothing),则使用 DefaultBinder。
- target
-
要在其上调用指定成员的 Object。
- args
-
包含传递给要调用的成员的参数的数组。
- modifiers
-
ParameterModifier 对象数组,表示与 args 数组中的相应元素关联的属性 (Attribute)。参数的关联的属性 (Attribute) 存储在成员的签名中。默认的联编程序不处理此参数。
- culture
-
表示要使用的全局化区域设置的 CultureInfo 对象,它对区域设置特定的转换可能是必需的,比如将数字 String 转换为 Double。
- 或 -
空引用(在 Visual Basic 中为 Nothing),表示使用当前线程的 CultureInfo。
- namedParameters
-
包含参数名称的数组,args 数组中的值被传递给这些参数。
返回值
表示被调用成员的返回值的 Object。
异常类型 | 条件 |
---|---|
ArgumentNullException |
invokeAttr 包含 CreateInstance,并且 typeName 为 空引用(在 Visual Basic 中为 Nothing)。 |
ArgumentException |
args 是多维的。 - 或 - modifiers 是多维的。 - 或 - args 和 modifiers 的长度不同。 - 或 - invokeAttr 不是有效的 BindingFlags 属性。 - 或 - invokeAttr 包含与 InvokeMethod、GetField、SetField、GetProperty 或 SetProperty 组合的 CreateInstance。 - 或 - invokeAttr 同时包含 GetField 和 SetField。 - 或 - invokeAttr 同时包含 GetProperty 和 SetProperty。 - 或 - invokeAttr 包含与 SetField 或 SetProperty 组合的 InvokeMethod。 - 或 - invokeAttr 包含 SetField,并且 args 具有一个以上的元素。 - 或 - 命名参数数组大于此参数数组。 - 或 - 对 COM 对象调用此方法,且未传入下列绑定标志之一:BindingFlags.InvokeMethod、BindingFlags.GetProperty、BindingFlags.SetProperty、BindingFlags.PutDispProperty或 BindingFlags.PutRefDispProperty。 - 或 - 某个命名参数数组包含一个为 空引用(在 Visual Basic 中为 Nothing) 的字符串。 |
MethodAccessException |
指定的成员是类初始值设定项。 |
MissingFieldException |
找不到该字段或属性。 |
MissingMethodException |
找不到此方法。 - 或 - 当前 Type 对象表示包含开放类型参数的类型,即 ContainsGenericParameters 返回 true。 |
TargetException |
在 target 上无法调用指定的成员。 |
AmbiguousMatchException |
多个方法匹配绑定条件。 |
InvokeMember 调用构造函数成员或方法成员,获取或设置属性成员,获取或设置数据字段成员,或者获取或设置数组成员的元素。
当调用 IDispatch 成员时,可以使用字符串格式“[DispID=##]”指定 DispID 而非成员名称。例如,如果 MyComMethod 的 DispID 为 3,则可以指定字符串“[DispID=3]”而不是“MyComMethod”。按 DispID 调用成员比按名称查找成员快。在复杂的聚合方案中,DispID 有时是调用所需成员的唯一方式。
尽管默认的联编程序不处理 ParameterModifier 或 CultureInfo(modifiers 和 culture 参数),您仍然可以使用抽象System.Reflection.Binder 类编写会处理 modifiers 和 culture 的自定义联编程序。仅当通过 COM interop 进行调用时才使用 ParameterModifier,并且仅处理通过引用传递的参数。
args 数组和 modifiers 数组的长度相同。args 数组中指定的参数可具有下列在 modifiers 数组中指定的属性 (Attribute):pdIn、pdOut、pdLcid、pdRetval、pdOptional 和 pdHasDefault,它们分别表示 [In]、[Out]、[lcid]、[retval]、[optional] 和一个指定参数是否有默认值的值。参数的关联属性 (Attribute) 存储在元数据中并且增强了交互操作。
namedParameters 数组中的每一个参数获取 args 数组中相应元素中的值。如果 args 的长度大于 namedParameters 的长度,则按顺序传递剩余的参数值。
下列 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 无效。
有关更多信息,请参见 System.Reflection.BindingFlags。
如果下列条件为真,则将调用方法:
-
方法声明中的参数个数等于 args 数组中的参数个数(除非在成员上定义了默认参数)。
-
每个参数 (argument) 的类型可以被联编程序转换为参数 (parameter) 类型。
联编程序将查找所有的匹配方法。查找这些方法时基于所请求的绑定类型(BindingFlags 值InvokeMethod、GetProperty 等)。方法集按名称、参数数目、联编程序中定义的一组搜索修饰符进行筛选。
选择方法后,方法即被调用。同时检查可访问性。搜索可能基于与此方法关联的可访问性属性来控制搜索哪些方法集。Binder 类的 Binder.BindToMethod 方法负责选择要调用的方法。默认联编程序选择最精确的匹配。
InvokeMember 可用于调用带参数(这些参数有默认值)的方法。要绑定到这些方法,“反射”要求指定BindingFlags.OptionalParamBinding。对于具有默认值的参数,可以提供不同的值,也可以提供 Missing.Value 以使用默认值。
例如,请看这个方法 MyMethod(int x, float y = 2.0)。若要调用只带第一个参数的此方法,即 MyMethod(4),请传递上面的绑定标志之一并传递两个参数,即第一个参数为 4,第二个参数为 Missing.Value。除非使用 Missing.Value,否则不能省略 Invoke 方法的可选参数。如果必须这样做,则使用 InvokeMember 代替。
对于完全受信任的代码将忽略访问限制;即,只要代码是完全受信任的,就可以通过 System.Reflection 访问和调用私有的构造函数、方法、字段和属性。
通过指定 BindingFlags.SetField,可以用 Type.InvokeMember 将某个字段设置为特定值。例如,如果要设置 C 类上名为 F 的公共实例字段,并且 F 为 String,则可使用下列代码:
typeof(C).InvokeMember("F", BindingFlags.SetField, null, C, new Object{"strings new value"}, null, null, null);
如果 F 为 String[],则可使用下列代码:
typeof(C).InvokeMember("F", BindingFlags.SetField, null, C, new Object{new String[]{"a","z","c","d"}, null, null, null);
这会将字段 F 初始化为此新数组。还可用 Type.InvokeMember 设置数组中的某个位置(通过提供值索引),然后通过使用下列代码设置下一个值:
typeof(C).InvokeMember("F", BindingFlags.SetField, null, C, new Object{1, "b"}, null, null, null);
这会将 F 在数组中所占据的字符串“z”更改为字符串“b”。