/// <summary> /// This method applies name filtering to a set of members. /// </summary> public static List <T> Filter <T>(this IEnumerable <T> members, FasterflectFlags bindingFlags, params string[] names) where T : MemberInfo { List <T> result = new List <T>(); bool ignoreCase = bindingFlags.IsSet(FasterflectFlags.IgnoreCase); bool isPartial = bindingFlags.IsSet(FasterflectFlags.PartialNameMatch); bool trimExplicit = bindingFlags.IsSet(FasterflectFlags.TrimExplicitlyImplemented); foreach (T member in members) { string memberName = trimExplicit ? member.Name.TrimExplicitlyImplementedName() : member.Name; for (int j = 0; j < names.Length; j++) { string name = names[j]; StringComparison comparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; bool match = isPartial ? memberName.Contains(name) : memberName.Equals(name, comparison); if (match) { result.Add(member); break; } } } return(result); }
/// <summary> /// This method applies flags-based filtering to a set of members. /// </summary> public static List <T> Filter <T>(this IEnumerable <T> members, FasterflectFlags bindingFlags) where T : MemberInfo { List <T> result = new List <T>(); List <string> properties = new List <string>(); bool excludeHidden = bindingFlags.IsSet(FasterflectFlags.ExcludeHiddenMembers); bool excludeBacking = bindingFlags.IsSet(FasterflectFlags.ExcludeBackingMembers); bool excludeExplicit = bindingFlags.IsSet(FasterflectFlags.ExcludeExplicitlyImplemented); foreach (T member in members) { bool exclude = false; if (excludeHidden) { MethodBase method = member as MethodBase; // filter out anything but methods/constructors based on their name only exclude |= method == null && result.Any(m => m.Name == member.Name); // filter out methods that do not have a unique signature (this prevents overloads from being excluded by the ExcludeHiddenMembers flag) exclude |= method != null && result.Where(m => m is MethodBase).Cast <MethodBase>().Any(m => m.Name == member.Name && m.HasParameterSignature(method.GetParameters())); } if (!exclude && excludeBacking) { exclude |= member is FieldInfo && member.Name[0] == '<'; if (member is MethodInfo methodInfo) { // filter out property backing methods exclude |= member.Name.Length > 4 && member.Name.Substring(1, 3) == "et_"; // filter out base implementations when an overrride exists exclude |= result.ContainsOverride(methodInfo); } if (member is PropertyInfo property) { MethodInfo propertyGetter = property.GetGetMethod(true); exclude |= propertyGetter.IsVirtual && properties.Contains(property.Name); if (!exclude) { properties.Add(property.Name); } } } exclude |= excludeExplicit && member.Name.Contains(".") && !member.Name.IsReservedName(); if (exclude) { continue; } result.Add(member); } return(result); }
/// <summary> /// Gets all types in the given <paramref name="assembly"/> matching the specified /// <paramref name="bindingFlags"/> and the optional list <paramref name="names"/>. /// </summary> /// <param name="assembly">The assembly in which to look for types.</param> /// <param name="bindingFlags">The <see cref="BindingFlags"/> used to customize how results /// are filters. If the <see cref="FasterflectFlags.PartialNameMatch"/> option is specified any name /// comparisons will use <see cref="String.Contains(String)"/> instead of <see cref="String.Equals(string)"/>.</param> /// <param name="names">An optional list of names against which to filter the result. If this is /// <see langword="null"/> or left empty, all types are returned.</param> /// <returns>A list of all matching types. This method never returns null.</returns> public static IList <Type> Types(this Assembly assembly, FasterflectFlags bindingFlags, params string[] names) { Type[] types = assembly.GetTypes(); bool hasNames = names != null && names.Length > 0; bool partialNameMatch = bindingFlags.IsSet(FasterflectFlags.PartialNameMatch); return(hasNames ? types.Where(t => names.Any(n => partialNameMatch ? t.Name.Contains(n) : t.Name == n)).ToArray() : types); }
/// <summary> /// This method applies method parameter type filtering to a set of methods. /// </summary> public static List <T> Filter <T>(this IEnumerable <T> methods, FasterflectFlags bindingFlags, Type[] paramTypes) where T : MethodBase { List <T> result = new List <T>(); bool exact = bindingFlags.IsSet(FasterflectFlags.ExactBinding); foreach (T method in methods) { // verify parameters ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != paramTypes.Length) { continue; } // verify parameter type compatibility bool match = true; for (int j = 0; j < paramTypes.Length; j++) { Type type = paramTypes[j]; ParameterInfo parameter = parameters[j]; Type parameterType = parameter.ParameterType; bool ignoreParameterModifiers = !exact; if (ignoreParameterModifiers && parameterType.IsByRef) { string name = parameterType.FullName; parameterType = Type.GetType(name.Substring(0, name.Length - 1)) ?? parameterType; } match &= parameterType.IsGenericParameter || parameterType.ContainsGenericParameters || (exact ? type == parameterType : parameterType.IsAssignableFrom(type)); if (!match) { break; } } if (match) { result.Add(method); } } return(result); }