public abstract BindToField ( BindingFlags bindingAttr, Array match, object value, CultureInfo culture ) : |
||
bindingAttr | BindingFlags | |
match | Array | |
value | object | |
culture | CultureInfo | |
return |
public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) { return(_binder.BindToField(bindingAttr, match, value, culture)); }
public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) { // Did we specify an access type? //Console.WriteLine("InvokeAttr:" + (int) invokeAttr); if ((invokeAttr & (BindingFlags) BinderAccessMask) == 0) throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),"invokeAttr"); // Did we specify an CreateInstance and another access type? if ((invokeAttr & BindingFlags.CreateInstance) != 0 && (invokeAttr & (BindingFlags) BinderNonCreateInstance) != 0) throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),"invokeAttr"); // If they didn't specify a lookup, then we will provide the default lookup. if ((invokeAttr & (BindingFlags) LookupMask) == 0) { invokeAttr |= BindingFlags.Instance | BindingFlags.Public; if ((invokeAttr & BindingFlags.CreateInstance) == 0) invokeAttr |= BindingFlags.Static; } // if the number of names is bigger than the number of args we have a problem if (namedParameters != null && ((args == null && namedParameters.Length != 0) || (args != null && namedParameters.Length > args.Length))) throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"),"namedParameters"); if (namedParameters != null) for (int i=0;i<namedParameters.Length;i++) if (namedParameters[i] == null) throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),"namedParameters"); // The number of arguments to the method. We will only match // arguments that match directly. int argCnt = (args != null) ? args.Length : 0; // Without a binder we need to do use the default binder... if (binder == null) binder = DefaultBinder; bool bDefaultBinder = (binder == DefaultBinder); if ((invokeAttr & BindingFlags.CreateInstance) != 0) return Activator.CreateInstance(this,invokeAttr,binder,args,culture); // When calling on a managed component, we consider both PutDispProperty and // PutRefDispProperty to be equivalent to SetProperty. if ((invokeAttr & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0) invokeAttr |= BindingFlags.SetProperty; // For fields, methods and properties the name must be specified. if (name == null) throw new ArgumentNullException("name"); MethodInfo[] props=null; MethodInfo[] meths=null; // We will narrow down the search to a field first... FieldInfo selFld=null; // if we are looking for the default member, find it... if (name.Length == 0 || name.Equals("[DISPID=0]")) { name = GetDefaultMemberName(); if (name == null) { // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString name = "ToString"; } } // Fields if ((invokeAttr & BindingFlags.GetField) != 0 || (invokeAttr & BindingFlags.SetField) != 0) { FieldInfo[] flds=null; // validate the set/get stuff if (((invokeAttr & (BindingFlags) BinderGetSetField) ^ (BindingFlags) BinderGetSetField) == 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),"invokeAttr"); if (((invokeAttr & (BindingFlags) BinderSetInvokeField) ^ (BindingFlags)BinderSetInvokeField) == 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"invokeAttr"); bool fieldGet = ((invokeAttr & BindingFlags.GetField) != 0); if (fieldGet) { if ((invokeAttr & BindingFlags.SetProperty) != 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"invokeAttr"); } else { if ((invokeAttr & BindingFlags.GetProperty) != 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"invokeAttr"); } flds = GetMemberField(name,invokeAttr, false); // We are only doing a field/set get if (flds != null) { if (flds.Length != 1) { Object o; if (fieldGet) o = Empty.Value; else { if (args == null) throw new ArgumentNullException("args"); o = args[0]; } selFld = binder.BindToField(invokeAttr,flds,o,culture); } else { selFld = flds[0]; } } // If we are only set/get field we leave here with errors... if ((invokeAttr & (BindingFlags) BinderNonFieldGetSet) == 0) { if (flds == null) throw new MissingFieldException(FullName, name); if (flds.Length == 1) selFld = flds[0]; else if (selFld == null) throw new MissingFieldException(FullName, name); } // If we can continue we leave if we found a field. Fields // now have the highest priority. if (selFld != null) { //Console.WriteLine(selFld.FieldType.Name); //Console.WriteLine("argCnt:" + argCnt); // For arrays we are going to see if they are trying to access the array if (selFld.FieldType.IsArray || selFld.FieldType == typeof(System.Array)) { int idxCnt; if ((invokeAttr & BindingFlags.GetField) != 0) { idxCnt = argCnt; } else { idxCnt = argCnt - 1; } if (idxCnt > 0) { // Verify that all of the index values are ints int[] idx = new int[idxCnt]; for (int i=0;i<idxCnt;i++) { try { idx[i] = ((IConvertible)args[i]).ToInt32(null); } catch (InvalidCastException) { throw new ArgumentException(Environment.GetResourceString("Arg_IndexMustBeInt")); } } // Set or get the value... Array a = (Array) selFld.GetValue(target); // Set or get the value in the array if ((invokeAttr & BindingFlags.GetField) != 0) { return a.GetValue(idx); } else { a.SetValue(args[idxCnt],idx); return null; } } } else { // This is not an array so we validate that the arg count is correct. if ((invokeAttr & BindingFlags.GetField) != 0 && argCnt != 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),"invokeAttr"); if ((invokeAttr & BindingFlags.SetField) != 0 && argCnt != 1) throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),"invokeAttr"); } // Set the field... if (fieldGet) return selFld.GetValue(target); else { selFld.SetValue(target,args[0],invokeAttr,binder,culture); return null; } } } // Properties MethodBase invokeMethod; bool useCache = false; // Note that when we add something to the cache, we are careful to ensure // that the actual args matches the parameters of the method. Otherwise, // some default argument processing has occurred. We don't want anyone // else with the same (insufficient) number of actual arguments to get a // cache hit because then they would bypass the default argument processing // and the invocation would fail. if (bDefaultBinder && namedParameters == null && argCnt < 6) useCache = true; if (useCache) { invokeMethod = nGetMethodFromCache (name, invokeAttr, argCnt, args); if (invokeMethod != null) return ((MethodInfo) invokeMethod).Invoke(target,invokeAttr,binder,args,culture); } if ((invokeAttr & BindingFlags.GetProperty) != 0 || (invokeAttr & BindingFlags.SetProperty) != 0) { if (((invokeAttr & (BindingFlags) BinderGetSetProperty) ^ (BindingFlags) BinderGetSetProperty) == 0) throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"),"invokeAttr"); if (((invokeAttr & (BindingFlags) BinderSetInvokeProperty) ^ (BindingFlags) BinderSetInvokeProperty) == 0) throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"),"invokeAttr"); bool propGet = ((invokeAttr & BindingFlags.GetProperty) != 0); if (propGet) { if ((invokeAttr & BindingFlags.SetField) != 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"invokeAttr"); } else { if ((invokeAttr & BindingFlags.GetField) != 0) throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"invokeAttr"); } props = GetMemberProperties(name,invokeAttr,argCnt, false); } if ((invokeAttr & BindingFlags.InvokeMethod) != 0) { meths = GetMemberMethod(name, invokeAttr, CallingConventions.Any, null, argCnt, false); } if (meths == null && props == null) throw new MissingMethodException(FullName, name); // if either props or meths is null then we simply work with // the other one. (One must be non-null because of the if statement above) if (props == null) { if (argCnt == 0 && meths[0].GetParameters().Length == 0 && (invokeAttr & BindingFlags.OptionalParamBinding) == 0) { if (useCache && argCnt == meths[0].GetParameters().Length) nAddMethodToCache(name,invokeAttr,argCnt,args,meths[0]); return meths[0].Invoke(target,invokeAttr,binder,args,culture); } else { if (args == null) args = new Object[0]; Object state = null; invokeMethod = binder.BindToMethod(invokeAttr,meths,ref args,modifiers,culture,namedParameters, out state); if (invokeMethod == null) throw new MissingMethodException(FullName, name); if (useCache && argCnt == invokeMethod.GetParameters().Length) nAddMethodToCache(name,invokeAttr,argCnt,args,invokeMethod); Object result = ((MethodInfo) invokeMethod).Invoke(target,invokeAttr,binder,args,culture); if (state != null) binder.ReorderArgumentArray(ref args, state); return result; } } if (meths == null) { if (argCnt == 0 && props[0].GetParameters().Length == 0 && (invokeAttr & BindingFlags.OptionalParamBinding) == 0) { if (useCache && argCnt == props[0].GetParameters().Length) nAddMethodToCache(name,invokeAttr,argCnt,args,props[0]); return props[0].Invoke(target,invokeAttr,binder,args,culture); } else { if (args == null) args = new Object[0]; Object state = null; invokeMethod = binder.BindToMethod(invokeAttr,props,ref args,modifiers,culture,namedParameters, out state); if (invokeMethod == null) throw new MissingMethodException(FullName, name); if (useCache && argCnt == invokeMethod.GetParameters().Length) nAddMethodToCache(name,invokeAttr,argCnt,args,invokeMethod); Object result = ((MethodInfo) invokeMethod).Invoke(target,invokeAttr,binder,args,culture); if (state != null) binder.ReorderArgumentArray(ref args, state); return result; } } // Now we have both methods and properties... MethodInfo[] p = new MethodInfo[props.Length + meths.Length]; Array.Copy(meths,p,meths.Length); Array.Copy(props,0,p,meths.Length,props.Length); if (args == null) args = new Object[0]; Object binderState = null; invokeMethod = binder.BindToMethod(invokeAttr,p,ref args,modifiers,culture,namedParameters, out binderState); if (invokeMethod == null) throw new MissingMethodException(FullName, name); if (useCache && argCnt == invokeMethod.GetParameters().Length) nAddMethodToCache(name,invokeAttr,argCnt,args,invokeMethod); Object res = ((MethodInfo) invokeMethod).Invoke(target,invokeAttr,binder,args,culture); if (binderState != null) { binder.ReorderArgumentArray(ref args, binderState); } return res; }