private static BindingFlags ToBindingFlags(this MemberFlags flags, bool flatten)
        {
            BindingFlags result = default(BindingFlags);

            if (flags.HasMemberFlag(MemberFlags.Instance))
            {
                result |= BindingFlags.Instance;
            }
            if (flags.HasMemberFlag(MemberFlags.Static))
            {
                result |= BindingFlags.Static;
            }
            if (flags.HasMemberFlag(MemberFlags.NonPublic))
            {
                result |= BindingFlags.NonPublic;
            }
            if (flags.HasMemberFlag(MemberFlags.Public))
            {
                result |= BindingFlags.Public;
            }
            if (flatten)
            {
                result |= BindingFlags.FlattenHierarchy;
            }
            return(result);
        }
 private static bool FilterMethod(MethodBase method, MemberFlags flags)
 {
     if (method == null)
     {
         return(false);
     }
     return(((flags.HasMemberFlag(MemberFlags.Static) && method.IsStatic) ||
             flags.HasMemberFlag(MemberFlags.Instance) && !method.IsStatic) &&
            ((flags.HasMemberFlag(MemberFlags.NonPublic) && !method.IsPublic) ||
             flags.HasMemberFlag(MemberFlags.Public) && method.IsPublic));
 }
 private static bool FilterField(FieldInfo field, MemberFlags flags)
 {
     if (field == null)
     {
         return(false);
     }
     return(((flags.HasMemberFlag(MemberFlags.Static) && field.IsStatic) ||
             flags.HasMemberFlag(MemberFlags.Instance) && !field.IsStatic) &&
            ((flags.HasMemberFlag(MemberFlags.NonPublic) && !field.IsPublic) ||
             flags.HasMemberFlag(MemberFlags.Public) && field.IsPublic));
 }
        public static MethodInfo GetMethodEx([NotNull] this Type type, string name, MemberFlags flags = MemberFlags.Public | MemberFlags.Static | MemberFlags.Instance)
        {
            Should.NotBeNull(type, nameof(type));
            var bindingFlags = flags.ToBindingFlags(false);
            var method       = type.GetMethod(name, bindingFlags | BindingFlags.FlattenHierarchy);

            if (method != null || !flags.HasMemberFlag(MemberFlags.NonPublic))
            {
                return(method);
            }
            bindingFlags |= BindingFlags.DeclaredOnly;
            type          = type.BaseType;
            while (type != null)
            {
                var result = type.GetMethod(name, bindingFlags);
                if (result != null)
                {
                    if (method != null)
                    {
                        throw new AmbiguousMatchException();
                    }
                    method = result;
                }
                type = type == typeof(object) ? null : type.BaseType;
            }
            return(method);
        }
        public static ICollection <MethodInfo> GetMethodsEx([NotNull] this Type type, MemberFlags flags = MemberFlags.Public | MemberFlags.Static | MemberFlags.Instance)
        {
            Should.NotBeNull(type, nameof(type));
            var bindingFlags = flags.ToBindingFlags(false);

            if (flags.HasMemberFlag(MemberFlags.NonPublic))
            {
                bindingFlags |= BindingFlags.DeclaredOnly;
                var list = new List <MethodInfo>();
                while (type != null)
                {
                    list.AddRange(type.GetMethods(bindingFlags));
                    type = type == typeof(object) ? null : type.BaseType;
                }
                return(list);
            }
            return(type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy));
        }
        public static EventInfo GetEventEx([NotNull] this Type type, string name, MemberFlags flags = MemberFlags.Public | MemberFlags.Static | MemberFlags.Instance)
        {
            Should.NotBeNull(type, nameof(type));
            var bindingFlags = flags.ToBindingFlags(false);
            var @event       = type.GetEvent(name, bindingFlags | BindingFlags.FlattenHierarchy);

            if (@event != null || !flags.HasMemberFlag(MemberFlags.NonPublic))
            {
                return(@event);
            }
            bindingFlags |= BindingFlags.DeclaredOnly;
            type          = type.BaseType;
            while (type != null)
            {
                @event = type.GetEvent(name, bindingFlags);
                if (@event != null)
                {
                    return(@event);
                }
                type = type == typeof(object) ? null : type.BaseType;
            }
            return(null);
        }