System.MonoType.InvokeMember C# (CSharp) Method

InvokeMember() public method

public InvokeMember ( string name, BindingFlags invokeAttr, Binder binder, object target, object args, ParameterModifier modifiers, CultureInfo culture, string namedParameters ) : object
name string
invokeAttr BindingFlags
binder System.Reflection.Binder
target object
args object
modifiers System.Reflection.ParameterModifier
culture System.Globalization.CultureInfo
namedParameters string
return object
		public override object InvokeMember (string name, BindingFlags invokeAttr,
						     Binder binder, object target, object[] args,
						     ParameterModifier[] modifiers,
						     CultureInfo culture, string[] namedParameters)
		{
#if NET_2_0
			const string bindingflags_arg = "bindingFlags";
#else
			const string bindingflags_arg = "invokeAttr";
#endif


			if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
				if ((invokeAttr & (BindingFlags.GetField |
						BindingFlags.GetField | BindingFlags.GetProperty |
						BindingFlags.SetProperty)) != 0)
					throw new ArgumentException (bindingflags_arg);
			} else if (name == null)
				throw new ArgumentNullException ("name");
			if ((invokeAttr & BindingFlags.GetField) != 0 && (invokeAttr & BindingFlags.SetField) != 0)
				throw new ArgumentException ("Cannot specify both Get and Set on a field.", bindingflags_arg);
			if ((invokeAttr & BindingFlags.GetProperty) != 0 && (invokeAttr & BindingFlags.SetProperty) != 0)
				throw new ArgumentException ("Cannot specify both Get and Set on a property.", bindingflags_arg);
			if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
				if ((invokeAttr & BindingFlags.SetField) != 0)
					throw new ArgumentException ("Cannot specify Set on a field and Invoke on a method.", bindingflags_arg);
				if ((invokeAttr & BindingFlags.SetProperty) != 0)
					throw new ArgumentException ("Cannot specify Set on a property and Invoke on a method.", bindingflags_arg);
			}
			if ((namedParameters != null) && ((args == null) || args.Length < namedParameters.Length))
				throw new ArgumentException ("namedParameters cannot be more than named arguments in number");
			if ((invokeAttr & (BindingFlags.InvokeMethod|BindingFlags.CreateInstance|BindingFlags.GetField|BindingFlags.SetField|BindingFlags.GetProperty|BindingFlags.SetProperty)) == 0)
				throw new ArgumentException ("Must specify binding flags describing the invoke operation required.", bindingflags_arg);

			/* set some defaults if none are provided :-( */
			if ((invokeAttr & (BindingFlags.Public|BindingFlags.NonPublic)) == 0)
				invokeAttr |= BindingFlags.Public;
			if ((invokeAttr & (BindingFlags.Static|BindingFlags.Instance)) == 0)
				invokeAttr |= BindingFlags.Static|BindingFlags.Instance;

			if (binder == null)
				binder = Binder.DefaultBinder;
			if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
				/* the name is ignored */
				invokeAttr |= BindingFlags.DeclaredOnly;
				ConstructorInfo[] ctors = GetConstructors (invokeAttr);
				object state = null;
				MethodBase ctor = binder.BindToMethod (invokeAttr, ctors, ref args, modifiers, culture, namedParameters, out state);
				if (ctor == null) {
					if (this.IsValueType && args == null)
						return Activator.CreateInstanceInternal (this);
					
					throw new MissingMethodException ("Constructor on type '" + FullName + "' not found.");
				}
				object result = ctor.Invoke (target, invokeAttr, binder, args, culture);
				binder.ReorderArgumentArray (ref args, state);
				return result;
			}
			if (name == String.Empty && Attribute.IsDefined (this, typeof (DefaultMemberAttribute))) {
				DefaultMemberAttribute attr = (DefaultMemberAttribute) Attribute.GetCustomAttribute (this, typeof (DefaultMemberAttribute));
				name = attr.MemberName;
			}
			bool ignoreCase = (invokeAttr & BindingFlags.IgnoreCase) != 0;
			string throwMissingMethodDescription = null;
			bool throwMissingFieldException = false;
			
			if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
				MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
				object state = null;
				if (args == null)
					args = new object [0];
				MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
				if (m == null) {
					if (methods.Length > 0)
						throwMissingMethodDescription = "The best match for method " + name + " has some invalid parameter.";
					else
						throwMissingMethodDescription = "Cannot find method " + name + ".";
				} else {
					ParameterInfo[] parameters = m.GetParameters();
					for (int i = 0; i < parameters.Length; ++i) {
						if (System.Reflection.Missing.Value == args [i] && (parameters [i].Attributes & ParameterAttributes.HasDefault) != ParameterAttributes.HasDefault)
							throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
					}
					bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
						typeof (ParamArrayAttribute)) : false;
					if (hasParamArray)
						ReorderParamArrayArguments (ref args, m);
					object result = m.Invoke (target, invokeAttr, binder, args, culture);
					binder.ReorderArgumentArray (ref args, state);
					return result;
				}
			}
			if ((invokeAttr & BindingFlags.GetField) != 0) {
				FieldInfo f = GetField (name, invokeAttr);
				if (f != null) {
					return f.GetValue (target);
				} else if ((invokeAttr & BindingFlags.GetProperty) == 0) {
					throwMissingFieldException = true;
				}
				/* try GetProperty */
			} else if ((invokeAttr & BindingFlags.SetField) != 0) {
				FieldInfo f = GetField (name, invokeAttr);
				if (f != null) {
#if NET_2_0
					if (args == null)
						throw new ArgumentNullException ("providedArgs");
#endif
					if ((args == null) || args.Length != 1)
						throw new ArgumentException ("Only the field value can be specified to set a field value.", bindingflags_arg);
					f.SetValue (target, args [0]);
					return null;
				} else if ((invokeAttr & BindingFlags.SetProperty) == 0) {
					throwMissingFieldException = true;
				}
				/* try SetProperty */
			}
			if ((invokeAttr & BindingFlags.GetProperty) != 0) {
				PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
				object state = null;
				int i, count = 0;
				for (i = 0; i < properties.Length; ++i) {
					if ((properties [i].GetGetMethod (true) != null))
						count++;
				}
				MethodBase[] smethods = new MethodBase [count];
				count = 0;
				for (i = 0; i < properties.Length; ++i) {
					MethodBase mb = properties [i].GetGetMethod (true);
					if (mb != null)
						smethods [count++] = mb;
				}
				MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
				if (m == null) {
					throwMissingFieldException = true;
				} else {
					ParameterInfo[] parameters = m.GetParameters();
					bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
						typeof (ParamArrayAttribute)) : false;
					if (hasParamArray)
						ReorderParamArrayArguments (ref args, m);
					object result = m.Invoke (target, invokeAttr, binder, args, culture);
					binder.ReorderArgumentArray (ref args, state);
					return result;
				}
			} else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
				PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
				object state = null;
				int i, count = 0;
				for (i = 0; i < properties.Length; ++i) {
					if (properties [i].GetSetMethod (true) != null)
						count++;
				}
				MethodBase[] smethods = new MethodBase [count];
				count = 0;
				for (i = 0; i < properties.Length; ++i) {
					MethodBase mb = properties [i].GetSetMethod (true);
					if (mb != null)
						smethods [count++] = mb;
				}
				MethodBase m = binder.BindToMethod (invokeAttr, smethods, ref args, modifiers, culture, namedParameters, out state);
				if (m == null) {
					throwMissingFieldException = true;
				} else {
					ParameterInfo[] parameters = m.GetParameters();
					bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
						typeof (ParamArrayAttribute)) : false;
					if (hasParamArray)
						ReorderParamArrayArguments (ref args, m);
					object result = m.Invoke (target, invokeAttr, binder, args, culture);
					binder.ReorderArgumentArray (ref args, state);
					return result;
				}
			}
			if (throwMissingMethodDescription != null)
				throw new MissingMethodException(throwMissingMethodDescription);
			if (throwMissingFieldException)
				throw new MissingFieldException("Cannot find variable " + name + ".");

			return null;
		}