public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { // list of methods on this type according to the underlying ReflectionContext MethodInfo[] methods = base.GetMethods(bindingAttr); // Optimization: we currently don't support adding nonpublic or static property getters or setters, // so if Public or Instance is not set we don't need to check for new properties. bool getDeclaredOnly = (bindingAttr & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly; bool getInstance = (bindingAttr & BindingFlags.Instance) == BindingFlags.Instance; bool getPublic = (bindingAttr & BindingFlags.Public) == BindingFlags.Public; if (!getPublic || !getInstance) { return(methods); } List <MethodInfo> results = new List <MethodInfo>(methods); // in runtime reflection hidden methods are always returned in GetMethods foreach (PropertyInfo prop in NewProperties) { results.AddRange(prop.GetAccessors()); } // adding new methods declared on base types if (!getDeclaredOnly) { CustomType?baseType = BaseType as CustomType; while (baseType != null) { // We shouldn't add a base type method directly on a subtype. // A new method with a different ReflectedType should be used. foreach (PropertyInfo prop in baseType.NewProperties) { PropertyInfo inheritedProperty = new InheritedPropertyInfo(prop, this); results.AddRange(inheritedProperty.GetAccessors()); } baseType = baseType.BaseType as CustomType; } } return(results.ToArray()); }
protected override MethodInfo?GetMethodImpl(string name, BindingFlags bindingAttr, Binder?binder, CallingConventions callConvention, Type[]?types, ParameterModifier[]?modifiers) { MethodInfo?method = base.GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers); bool getIgnoreCase = (bindingAttr & BindingFlags.IgnoreCase) == BindingFlags.IgnoreCase; bool getDeclaredOnly = (bindingAttr & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly; bool getInstance = (bindingAttr & BindingFlags.Instance) == BindingFlags.Instance; bool getPublic = (bindingAttr & BindingFlags.Public) == BindingFlags.Public; // If the ReflectionContext adds a property with identical name and type to an existing property, // the behavior is unspecified. // In this implementation, we return the existing method. if (!getPublic || !getInstance) { return(method); } bool getPropertyGetter = false; bool getPropertySetter = false; StringComparison comparison = getIgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (name.Length > 4) { // Right now we don't support adding fabricated indexers on types getPropertyGetter = (types == null || types.Length == 0) && name.StartsWith("get_", comparison); if (!getPropertyGetter) { getPropertySetter = (types == null || types.Length == 1) && name.StartsWith("set_", comparison); } } // not a property getter or setter if (!getPropertyGetter && !getPropertySetter) { return(method); } // get the target property name by removing "get_" or "set_" string targetPropertyName = name.Substring(4); List <MethodInfo> matchingMethods = new List <MethodInfo>(); if (method != null) { matchingMethods.Add(method); } // in runtime reflection hidden methods are always returned in GetMethods foreach (PropertyInfo newDeclaredProperty in NewProperties) { if (string.Equals(newDeclaredProperty.Name, targetPropertyName, comparison)) { MethodInfo?accessor = getPropertyGetter ? newDeclaredProperty.GetGetMethod() : newDeclaredProperty.GetSetMethod(); if (accessor != null) { matchingMethods.Add(accessor); } } } // adding new methods declared on base types if (!getDeclaredOnly) { CustomType?baseType = BaseType as CustomType; while (baseType != null) { // We shouldn't add a base type method directly on a subtype. // A new method with a different ReflectedType should be used. foreach (PropertyInfo newBaseProperty in baseType.NewProperties) { if (string.Equals(newBaseProperty.Name, targetPropertyName, comparison)) { PropertyInfo inheritedProperty = new InheritedPropertyInfo(newBaseProperty, this); MethodInfo?accessor = getPropertyGetter ? inheritedProperty.GetGetMethod() : inheritedProperty.GetSetMethod(); if (accessor != null) { matchingMethods.Add(accessor); } } } baseType = baseType.BaseType as CustomType; } } if (matchingMethods.Count == 0) { return(null); } if (types == null || getPropertyGetter) { Debug.Assert(types == null || types.Length == 0); // matches any signature if (matchingMethods.Count == 1) { return(matchingMethods[0]); } else { throw new AmbiguousMatchException(); } } else { Debug.Assert(getPropertySetter && types != null && types.Length == 1); if (binder == null) { binder = Type.DefaultBinder; } return((MethodInfo?)binder.SelectMethod(bindingAttr, matchingMethods.ToArray(), types, modifiers)); } }