Пример #1
0
        /// <summary>
        /// Gets all methods on the given <paramref name="type"/> that match the given lookup criteria.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="genericTypes">If this parameter is supplied then only methods with the same generic parameter
        /// signature will be included in the result. The default behavior is to check only for assignment compatibility,
        /// but this can be changed to exact matching by passing <see href="Flags.ExactBinding"/>.</param>
        /// <param name="parameterTypes">If this parameter is supplied then only methods with the same parameter signature
        /// will be included in the result. The default behavior is to check only for assignment compatibility,
        /// but this can be changed to exact matching by passing <see href="Flags.ExactBinding"/>.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        /// the search behavior and result filtering.</param>
        /// <param name="names">The optional list of names against which to filter the result. If this parameter is
        /// <c>null</c> or empty no name filtering will be applied. The default behavior is to check for an exact,
        /// case-sensitive match. Pass <see href="Flags.ExcludeExplicitlyImplemented"/> to exclude explicitly implemented
        /// interface members, <see href="Flags.PartialNameMatch"/> to locate by substring, and
        /// <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <returns>A list of all matching methods. This value will never be null.</returns>
        public static IList <MethodInfo> Methods(this Type type, Type[] genericTypes, Type[] parameterTypes, Flags bindingFlags, params string[] names)
        {
            if (type == null || type == typeof(object))
            {
                return(new MethodInfo[0]);
            }
            bool recurse         = bindingFlags.IsNotSet(Flags.DeclaredOnly);
            bool hasNames        = names != null && names.Length > 0;
            bool hasTypes        = parameterTypes != null;
            bool hasGenericTypes = genericTypes != null && genericTypes.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (!recurse && !hasNames && !hasTypes && !hasSpecialFlags)
            {
                return(type.GetMethods(bindingFlags) ?? new MethodInfo[0]);
            }

            var methods = GetMethods(type, bindingFlags);

            methods = hasNames ? methods.Filter(bindingFlags, names) : methods;
            methods = hasGenericTypes ? methods.Filter(genericTypes) : methods;
            methods = hasTypes ? methods.Filter(bindingFlags, parameterTypes) : methods;
            methods = hasSpecialFlags ? methods.Filter(bindingFlags) : methods;
            return(methods);
        }
Пример #2
0
        /// <summary>
        /// Gets the field identified by <paramref name="name"/> on the given <paramref name="type"/>.
        /// Use the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single FieldInfo instance of the first found match or null if no match was found.</returns>
        public static FieldInfo Field(this Type type, string name, Flags bindingFlags)
        {
            // we need to check all fields to do partial name matches
            if (bindingFlags.IsAnySet(Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented))
            {
                return(type.Fields(bindingFlags, name).FirstOrDefault());
            }

            var result = type.GetTypeInfo().GetField(name, bindingFlags);

            if (result == null && bindingFlags.IsNotSet(Flags.DeclaredOnly))
            {
                if (type.GetTypeInfo().BaseType != typeof(object) && type.GetTypeInfo().BaseType != null)
                {
                    return(type.GetTypeInfo().BaseType.Field(name, bindingFlags));
                }
            }
            bool hasSpecialFlags = bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (hasSpecialFlags)
            {
                IList <FieldInfo> fields = new List <FieldInfo> {
                    result
                };
                fields = fields.Filter(bindingFlags);
                return(fields.Count > 0 ? fields[0] : null);
            }
            return(result);
        }
Пример #3
0
        /// <summary>
        /// Gets the method with the given <paramref name="name"/> and matching <paramref name="bindingFlags"/>
        /// on the given <paramref name="type"/> where the parameter types correspond in order with the
        /// supplied <paramref name="parameterTypes"/>.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="genericTypes">Type parameters if this is a generic method.</param>
        /// <param name="name">The name of the method to search for. This argument must be supplied. The
        ///   default behavior is to check for an exact, case-sensitive match. Pass <see href="Flags.ExplicitNameMatch"/>
        ///   to include explicitly implemented interface members, <see href="Flags.PartialNameMatch"/> to locate
        ///   by substring, and <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <param name="parameterTypes">If this parameter is supplied then only methods with the same parameter signature
        ///   will be included in the result. The default behavior is to check only for assignment compatibility,
        ///   but this can be changed to exact matching by passing <see href="Flags.ExactBinding"/>.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        ///   the search behavior and result filtering.</param>
        /// <returns>The specified method or null if no method was found. If there are multiple matches
        /// due to method overloading the first found match will be returned.</returns>
        public static MethodInfo Method(this Type type, Type[] genericTypes, string name, Type[] parameterTypes, Flags bindingFlags)
        {
            bool hasTypes        = parameterTypes != null;
            bool hasGenericTypes = genericTypes != null && genericTypes.Length > 0;
            // we need to check all methods to do partial name matches or complex parameter binding
            bool processAll = bindingFlags.IsAnySet(Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented);

            processAll |= hasTypes && bindingFlags.IsSet(Flags.IgnoreParameterModifiers);
            processAll |= hasGenericTypes;
            if (processAll)
            {
                return(type.Methods(genericTypes, parameterTypes, bindingFlags, name).FirstOrDefault().MakeGeneric(genericTypes));
            }

            var result = hasTypes ? type.GetMethod(name, bindingFlags, null, parameterTypes, null)
                                  : type.GetMethod(name, bindingFlags);

            if (result == null && bindingFlags.IsNotSet(Flags.DeclaredOnly))
            {
                if (type.BaseType != typeof(object) && type.BaseType != null)
                {
                    return(type.BaseType.Method(name, parameterTypes, bindingFlags).MakeGeneric(genericTypes));
                }
            }
            bool hasSpecialFlags = bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (hasSpecialFlags)
            {
                var methods = new List <MethodInfo> {
                    result
                }.Filter(bindingFlags);
                return((methods.Count > 0 ? methods[0] : null).MakeGeneric(genericTypes));
            }
            return(result.MakeGeneric(genericTypes));
        }
Пример #4
0
        /// <summary>
        /// Gets the property identified by <paramref name="name"/> on the given <paramref name="type"/>.
        /// Use the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single PropertyInfo instance of the first found match or null if no match was found.</returns>
        public static PropertyInfo Property(this Type type, string name, Flags bindingFlags)
        {
            // we need to check all properties to do partial name matches
            if (bindingFlags.IsAnySet(Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented))
            {
                return(type.Properties(bindingFlags, name).FirstOrDefault());
            }

            var result = type.GetTypeInfo().GetProperty(name, bindingFlags | Flags.DeclaredOnly);

            if (result == null && bindingFlags.IsNotSet(Flags.DeclaredOnly))
            {
                if (type.GetTypeInfo().BaseType != typeof(object) && type.GetTypeInfo().BaseType != null)
                {
                    return(type.GetTypeInfo().BaseType.Property(name, bindingFlags));
                }
            }
            bool hasSpecialFlags = bindingFlags.IsSet(Flags.ExcludeExplicitlyImplemented);

            if (hasSpecialFlags)
            {
                IList <PropertyInfo> properties = new List <PropertyInfo> {
                    result
                };
                properties = properties.Filter(bindingFlags);
                return(properties.Count > 0 ? properties[0] : null);
            }
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Gets the method with the given <paramref name="name"/> and matching <paramref name="bindingFlags"/>
        /// on the given <paramref name="type"/> where the parameter types correspond in order with the
        /// supplied <paramref name="parameterTypes"/>.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="genericTypes">Type parameters if this is a generic method.</param>
        /// <param name="name">The name of the method to search for. This argument must be supplied. The
        ///   default behavior is to check for an exact, case-sensitive match. Pass <see href="Flags.ExplicitNameMatch"/>
        ///   to include explicitly implemented interface members, <see href="Flags.PartialNameMatch"/> to locate
        ///   by substring, and <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <param name="parameterTypes">If this parameter is supplied then only methods with the same parameter signature
        ///   will be included in the result. The default behavior is to check only for assignment compatibility,
        ///   but this can be changed to exact matching by passing <see href="Flags.ExactBinding"/>.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        ///   the search behavior and result filtering.</param>
        /// <returns>The specified method or null if no method was found. If there are multiple matches
        /// due to method overloading the first found match will be returned.</returns>
        public static MethodInfo Method(this Type type, Type[] genericTypes, string name, Type[] parameterTypes, Flags bindingFlags)
        {
            bool hasTypes        = parameterTypes != null;
            bool hasGenericTypes = genericTypes != null && genericTypes.Length > 0;
            // we need to check all methods to do partial name matches or complex parameter binding
            bool processAll = bindingFlags.IsAnySet(Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented);

            processAll |= hasTypes && bindingFlags.IsSet(Flags.IgnoreParameterModifiers);
            processAll |= hasGenericTypes;
            if (processAll)
            {
                //TODO: Might have to do the same polymorphic parameter type check for generics
                return(type.Methods(genericTypes, parameterTypes, bindingFlags, name).FirstOrDefault().MakeGeneric(genericTypes));
            }

            //TODO: Check fasterflect cache first
            //TODO: Find out why we needed to call HasParameterSignature for polymorphism
            var result = hasTypes
                                ? type.GetTypeInfo().GetMethods(bindingFlags).FirstOrDefault(mi => mi.Name == name && mi.HasParameterSignature(parameterTypes))
                                : type.GetTypeInfo().GetMethod(name, bindingFlags);

            if (result == null && bindingFlags.IsNotSet(Flags.DeclaredOnly))
            {
                if (type.GetTypeInfo().BaseType != typeof(object) && type.GetTypeInfo().BaseType != null)
                {
                    //TODO: Added slow polymorphic type checking
                    //TODO: Check fasterflect cache first
                    if (hasTypes)
                    {
                        return(type.GetTypeInfo().BaseType.GetTypeInfo().GetMethods(bindingFlags).FirstOrDefault(mi => mi.Name == name && mi.HasParameterSignature(parameterTypes)));
                    }
                    else
                    {
                        return(type.GetTypeInfo().BaseType.Method(name, parameterTypes, bindingFlags));
                    }
                }
            }
            bool hasSpecialFlags =
                bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (hasSpecialFlags)
            {
                var methods = new List <MethodInfo> {
                    result
                }.Filter(bindingFlags);
                return((methods.Count > 0 ? methods[0] : null).MakeGeneric(genericTypes));
            }
            return(result.MakeGeneric(genericTypes));
        }
Пример #6
0
        /// <summary>
        /// Gets all properties on the given <paramref name="type"/> that match the specified <paramref name="bindingFlags"/>,
        /// including properties defined on base types.
        /// </summary>
        /// <returns>A list of all matching properties on the type. This value will never be null.</returns>
        public static IList <PropertyInfo> Properties(this Type type, Flags bindingFlags, params string[] names)
        {
            if (type == null || type == Constants.ObjectType)
            {
                return(Constants.EmptyPropertyInfoArray);
            }

            bool recurse         = bindingFlags.IsNotSet(Flags.DeclaredOnly);
            bool hasNames        = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (!recurse && !hasNames && !hasSpecialFlags)
            {
                return(type.GetTypeInfo().GetProperties(bindingFlags) ?? Constants.EmptyPropertyInfoArray);
            }

            var properties = GetProperties(type, bindingFlags);

            properties = hasSpecialFlags ? properties.Filter(bindingFlags) : properties;
            properties = hasNames ? properties.Filter(bindingFlags, names) : properties;
            return(properties);
        }
Пример #7
0
        /// <summary>
        /// Gets all fields on the given <paramref name="type"/> that match the specified <paramref name="bindingFlags"/>.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        /// the search behavior and result filtering.</param>
        /// <param name="names">The optional list of names against which to filter the result. If this parameter is
        /// <c>null</c> or empty no name filtering will be applied. The default behavior is to check for an exact,
        /// case-sensitive match. Pass <see href="Flags.ExcludeExplicitlyImplemented"/> to exclude explicitly implemented
        /// interface members, <see href="Flags.PartialNameMatch"/> to locate by substring, and
        /// <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <returns>A list of all matching fields on the type. This value will never be null.</returns>
        public static IList <FieldInfo> Fields(this Type type, Flags bindingFlags, params string[] names)
        {
            if (type == null || type == typeof(object))
            {
                return(new FieldInfo[0]);
            }

            bool recurse         = bindingFlags.IsNotSet(Flags.DeclaredOnly);
            bool hasNames        = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet(Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers);

            if (!recurse && !hasNames && !hasSpecialFlags)
            {
                return(type.GetTypeInfo().GetFields(bindingFlags) ?? new FieldInfo[0]);
            }

            var fields = GetFields(type, bindingFlags);

            fields = hasSpecialFlags ? fields.Filter(bindingFlags) : fields;
            fields = hasNames ? fields.Filter(bindingFlags, names) : fields;
            return(fields);
        }
Пример #8
0
        /// <summary>
        /// Gets the member identified by <paramref name="name"/> on the given <paramref name="type"/>. Use 
        /// the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single MemberInfo instance of the first found match or null if no match was found.</returns>
        public static MemberInfo Member( this Type type, string name, Flags bindingFlags )
        {
            // we need to check all members to do partial name matches
            if( bindingFlags.IsAnySet( Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented ) )
            {
                return type.Members( MemberTypes.All, bindingFlags, name ).FirstOrDefault();
            }

            IList<MemberInfo> result = type.GetMember( name, bindingFlags );
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );
            result = hasSpecialFlags && result.Count > 0 ? result.Filter( bindingFlags ) : result;
            bool found = result.Count > 0;

            if( !found && bindingFlags.IsNotSet( Flags.DeclaredOnly ) )
            {
                if( type.BaseType != typeof(object) && type.BaseType != null )
                {
                    return type.BaseType.Member( name, bindingFlags );
                }
            }
            return found ? result[ 0 ] : null;
        }
Пример #9
0
        /// <summary>
        /// Gets the member identified by <paramref name="name"/> on the given <paramref name="type"/>. Use 
        /// the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single MemberInfo instance of the first found match or null if no match was found.</returns>
        public static MemberInfo Member( this Type type, string name, Flags bindingFlags )
        {
            // we need to check all members to do partial name matches
            if( bindingFlags.IsAnySet( Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented ) )
            {
                return type.Members( MemberTypes.All, bindingFlags, name ).FirstOrDefault();
            }

            IList<MemberInfo> result = type.GetMember( name, bindingFlags );
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );
            result = hasSpecialFlags && result.Count > 0 ? result.Filter( bindingFlags ) : result;
            bool found = result.Count > 0;

            if( !found && bindingFlags.IsNotSet( Flags.DeclaredOnly ) )
            {
                if( type.BaseType != typeof(object) && type.BaseType != null )
                {
                    return type.BaseType.Member( name, bindingFlags );
                }
            }
            return found ? result[ 0 ] : null;
        }
Пример #10
0
        private static IList<MemberInfo> GetMembers( Type type, MemberTypes memberTypes, Flags bindingFlags )
        {
            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );

            if( ! recurse )
            {
                return type.FindMembers( memberTypes, bindingFlags, null, null );
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var members = new List<MemberInfo>();
            members.AddRange( type.FindMembers( memberTypes, bindingFlags, null, null ) );
            Type baseType = type.BaseType;
            while( baseType != null && baseType != typeof(object) )
            {
                members.AddRange( baseType.FindMembers( memberTypes, bindingFlags, null, null ) );
                baseType = baseType.BaseType;
            }
            return members;
        }
Пример #11
0
        /// <summary>
        /// Gets all members of the given <paramref name="memberTypes"/> on the given <paramref name="type"/> that 
        /// match the specified <paramref name="bindingFlags"/>, optionally filtered by the supplied <paramref name="names"/>
        /// list (in accordance with the given <paramref name="bindingFlags"/>).
        /// </summary>
        /// <param name="type">The type to reflect on.</param>
        /// <param name="memberTypes">The <see href="MemberTypes"/> to include in the result.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        /// the search behavior and result filtering.</param>
        /// <param name="names">The optional list of names against which to filter the result. If this parameter is
        /// <c>null</c> or empty no name filtering will be applied. The default behavior is to check for an exact, 
        /// case-sensitive match. Pass <see href="Flags.ExcludeExplicitlyImplemented"/> to exclude explicitly implemented 
        /// interface members, <see href="Flags.PartialNameMatch"/> to locate by substring, and 
        /// <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <returns>A list of all matching members on the type. This value will never be null.</returns>
        public static IList<MemberInfo> Members( this Type type, MemberTypes memberTypes, Flags bindingFlags,
            params string[] names)
        {
            if( type == null || type == typeof(object) )
            {
                return new MemberInfo[0];
            }

            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );
            bool hasNames = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );

            if( ! recurse && ! hasNames && ! hasSpecialFlags )
            {
                return type.FindMembers( memberTypes, bindingFlags, null, null );
            }

            var members = GetMembers( type, memberTypes, bindingFlags );
            members = hasSpecialFlags ? members.Filter( bindingFlags ) : members;
            members = hasNames ? members.Filter( bindingFlags, names ) : members;
            return members;
        }
Пример #12
0
        private static IList <PropertyInfo> GetProperties(Type type, Flags bindingFlags)
        {
            bool recurse = bindingFlags.IsNotSet(Flags.DeclaredOnly);

            if (!recurse)
            {
                return(type.GetTypeInfo().GetProperties(bindingFlags) ?? Constants.EmptyPropertyInfoArray);
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var properties = new List <PropertyInfo>();

            properties.AddRange(type.GetTypeInfo().GetProperties(bindingFlags));
            Type baseType = type.GetTypeInfo().BaseType;

            while (baseType != null && baseType != typeof(object))
            {
                properties.AddRange(baseType.GetTypeInfo().GetProperties(bindingFlags));
                baseType = baseType.GetTypeInfo().BaseType;
            }
            return(properties);
        }
Пример #13
0
        private static IList <MethodInfo> GetMethods(Type type, Flags bindingFlags)
        {
            bool recurse = bindingFlags.IsNotSet(Flags.DeclaredOnly);

            if (!recurse)
            {
                return(type.GetMethods(bindingFlags) ?? new MethodInfo[0]);
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var methods = new List <MethodInfo>();

            methods.AddRange(type.GetMethods(bindingFlags));
            Type baseType = type.BaseType;

            while (baseType != null && baseType != typeof(object))
            {
                methods.AddRange(baseType.GetMethods(bindingFlags));
                baseType = baseType.BaseType;
            }
            return(methods);
        }
Пример #14
0
        /// <summary>
        /// Gets all properties on the given <paramref name="type"/> that match the specified <paramref name="bindingFlags"/>,
        /// including properties defined on base types.
        /// </summary>
        /// <returns>A list of all matching properties on the type. This value will never be null.</returns>
        public static IList<PropertyInfo> Properties( this Type type, Flags bindingFlags, params string[] names )
        {
            if (type == null || type == Constants.ObjectType)
            {
                return Constants.EmptyPropertyInfoArray;
            }

            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );
            bool hasNames = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );

            if( ! recurse && ! hasNames && ! hasSpecialFlags )
            {
                return type.GetProperties( bindingFlags ) ?? Constants.EmptyPropertyInfoArray;
            }

            var properties = GetProperties( type, bindingFlags );
            properties = hasSpecialFlags ? properties.Filter( bindingFlags ) : properties;
            properties = hasNames ? properties.Filter( bindingFlags, names ) : properties;
            return properties;
        }
Пример #15
0
        /// <summary>
        /// Gets the field identified by <paramref name="name"/> on the given <paramref name="type"/>. 
        /// Use the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single FieldInfo instance of the first found match or null if no match was found.</returns>
        public static FieldInfo Field( this Type type, string name, Flags bindingFlags )
        {
            // we need to check all fields to do partial name matches
            if( bindingFlags.IsAnySet( Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented ) )
            {
                return type.Fields( bindingFlags, name ).FirstOrDefault();
            }

            var result = type.GetField( name, bindingFlags );
            if( result == null && bindingFlags.IsNotSet( Flags.DeclaredOnly ) )
            {
                if( type.BaseType != typeof(object) && type.BaseType != null )
                {
                    return type.BaseType.Field( name, bindingFlags );
                }
            }
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );
            if( hasSpecialFlags )
            {
                IList<FieldInfo> fields = new List<FieldInfo> { result };
                fields = fields.Filter( bindingFlags );
                return fields.Count > 0 ? fields[ 0 ] : null;
            }
            return result;
        }
Пример #16
0
        private static IList<FieldInfo> GetFields( Type type, Flags bindingFlags )
        {
            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );

            if( ! recurse )
            {
                return type.GetFields( bindingFlags ) ?? new FieldInfo[0];
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var fields = new List<FieldInfo>();
            fields.AddRange( type.GetFields( bindingFlags ) );
            Type baseType = type.BaseType;
            while( baseType != null && baseType != typeof(object) )
            {
                fields.AddRange( baseType.GetFields( bindingFlags ) );
                baseType = baseType.BaseType;
            }
            return fields;
        }
Пример #17
0
        /// <summary>
        /// Gets all fields on the given <paramref name="type"/> that match the specified <paramref name="bindingFlags"/>.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        /// the search behavior and result filtering.</param>
        /// <param name="names">The optional list of names against which to filter the result. If this parameter is
        /// <c>null</c> or empty no name filtering will be applied. The default behavior is to check for an exact, 
        /// case-sensitive match. Pass <see href="Flags.ExcludeExplicitlyImplemented"/> to exclude explicitly implemented 
        /// interface members, <see href="Flags.PartialNameMatch"/> to locate by substring, and 
        /// <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <returns>A list of all matching fields on the type. This value will never be null.</returns>
        public static IList<FieldInfo> Fields( this Type type, Flags bindingFlags, params string[] names )
        {
            if( type == null || type == typeof(object) )
            {
                return new FieldInfo[0];
            }

            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );
            bool hasNames = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );

            if( ! recurse && ! hasNames && ! hasSpecialFlags )
            {
                return type.GetFields( bindingFlags ) ?? new FieldInfo[0];
            }

            var fields = GetFields( type, bindingFlags );
            fields = hasSpecialFlags ? fields.Filter( bindingFlags ) : fields;
            fields = hasNames ? fields.Filter( bindingFlags, names ) : fields;
            return fields;
        }
Пример #18
0
        /// <summary>
        /// Gets all members of the given <paramref name="memberTypes"/> on the given <paramref name="type"/> that 
        /// match the specified <paramref name="bindingFlags"/>, optionally filtered by the supplied <paramref name="names"/>
        /// list (in accordance with the given <paramref name="bindingFlags"/>).
        /// </summary>
        /// <param name="type">The type to reflect on.</param>
        /// <param name="memberTypes">The <see href="MemberTypes"/> to include in the result.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        /// the search behavior and result filtering.</param>
        /// <param name="names">The optional list of names against which to filter the result. If this parameter is
        /// <c>null</c> or empty no name filtering will be applied. The default behavior is to check for an exact, 
        /// case-sensitive match. Pass <see href="Flags.ExcludeExplicitlyImplemented"/> to exclude explicitly implemented 
        /// interface members, <see href="Flags.PartialNameMatch"/> to locate by substring, and 
        /// <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <returns>A list of all matching members on the type. This value will never be null.</returns>
        public static IList<MemberInfo> Members( this Type type, MemberTypes memberTypes, Flags bindingFlags,
                                                 params string[] names )
        {
            if( type == null || type == typeof(object) )
            {
                return new MemberInfo[0];
            }

            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );
            bool hasNames = names != null && names.Length > 0;
            bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );

            if( ! recurse && ! hasNames && ! hasSpecialFlags )
            {
                return type.FindMembers( memberTypes, bindingFlags, null, null );
            }

            var members = GetMembers( type, memberTypes, bindingFlags );
            members = hasSpecialFlags ? members.Filter( bindingFlags ) : members;
            members = hasNames ? members.Filter( bindingFlags, names ) : members;
            return members;
        }
Пример #19
0
        private static IList<MemberInfo> GetMembers( Type type, MemberTypes memberTypes, Flags bindingFlags )
        {
            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );

            if( ! recurse )
            {
                return type.FindMembers( memberTypes, bindingFlags, null, null );
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var members = new List<MemberInfo>();
            members.AddRange( type.FindMembers( memberTypes, bindingFlags, null, null ) );
            Type baseType = type.BaseType;
            while( baseType != null && baseType != typeof(object) )
            {
                members.AddRange( baseType.FindMembers( memberTypes, bindingFlags, null, null ) );
                baseType = baseType.BaseType;
            }
            return members;
        }
Пример #20
0
        private static IList<PropertyInfo> GetProperties( Type type, Flags bindingFlags )
        {
            bool recurse = bindingFlags.IsNotSet( Flags.DeclaredOnly );

            if( ! recurse )
            {
                return type.GetProperties( bindingFlags ) ?? Constants.EmptyPropertyInfoArray;
            }

            bindingFlags |= Flags.DeclaredOnly;
            bindingFlags &= ~BindingFlags.FlattenHierarchy;

            var properties = new List<PropertyInfo>();
            properties.AddRange( type.GetProperties( bindingFlags ) );
            Type baseType = type.BaseType;
            while( baseType != null && baseType != typeof(object) )
            {
                properties.AddRange( baseType.GetProperties( bindingFlags ) );
                baseType = baseType.BaseType;
            }
            return properties;
        }
Пример #21
0
        /// <summary>
        /// Gets the property identified by <paramref name="name"/> on the given <paramref name="type"/>. 
        /// Use the <paramref name="bindingFlags"/> parameter to define the scope of the search.
        /// </summary>
        /// <returns>A single PropertyInfo instance of the first found match or null if no match was found.</returns>
        public static PropertyInfo Property( this Type type, string name, Flags bindingFlags )
        {
            // we need to check all properties to do partial name matches
            if( bindingFlags.IsAnySet( Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented ) )
            {
                return type.Properties( bindingFlags, name ).FirstOrDefault();
            }

            var result = type.GetProperty( name, bindingFlags | Flags.DeclaredOnly );
            if( result == null && bindingFlags.IsNotSet( Flags.DeclaredOnly ) )
            {
                if( type.BaseType != typeof(object) && type.BaseType != null )
                {
                    return type.BaseType.Property( name, bindingFlags );
                }
            }
            bool hasSpecialFlags = bindingFlags.IsSet( Flags.ExcludeExplicitlyImplemented );
            if( hasSpecialFlags )
            {
                IList<PropertyInfo> properties = new List<PropertyInfo> { result };
                properties = properties.Filter( bindingFlags );
                return properties.Count > 0 ? properties[ 0 ] : null;
            }
            return result;
        }
        /// <summary>
        /// Gets the method with the given <paramref name="name"/> and matching <paramref name="bindingFlags"/>
        /// on the given <paramref name="type"/> where the parameter types correspond in order with the
        /// supplied <paramref name="parameterTypes"/>.
        /// </summary>
        /// <param name="type">The type on which to reflect.</param>
        /// <param name="genericTypes">Type parameters if this is a generic method.</param>
        /// <param name="name">The name of the method to search for. This argument must be supplied. The 
        ///   default behavior is to check for an exact, case-sensitive match. Pass <see href="Flags.ExplicitNameMatch"/> 
        ///   to include explicitly implemented interface members, <see href="Flags.PartialNameMatch"/> to locate
        ///   by substring, and <see href="Flags.IgnoreCase"/> to ignore case.</param>
        /// <param name="parameterTypes">If this parameter is supplied then only methods with the same parameter signature
        ///   will be included in the result. The default behavior is to check only for assignment compatibility,
        ///   but this can be changed to exact matching by passing <see href="Flags.ExactBinding"/>.</param>
        /// <param name="bindingFlags">The <see cref="BindingFlags"/> or <see cref="Flags"/> combination used to define
        ///   the search behavior and result filtering.</param>
        /// <returns>The specified method or null if no method was found. If there are multiple matches
        /// due to method overloading the first found match will be returned.</returns>
        public static MethodInfo Method( this Type type, Type[] genericTypes, string name, Type[] parameterTypes, Flags bindingFlags )
        {
			bool hasTypes = parameterTypes != null;
        	bool hasGenericTypes = genericTypes != null && genericTypes.Length > 0;
            // we need to check all methods to do partial name matches or complex parameter binding
        	bool processAll = bindingFlags.IsAnySet( Flags.PartialNameMatch | Flags.TrimExplicitlyImplemented );
        	processAll |= hasTypes && bindingFlags.IsSet( Flags.IgnoreParameterModifiers );
        	processAll |= hasGenericTypes;
            if( processAll )
            {
                return type.Methods( genericTypes, parameterTypes, bindingFlags, name ).FirstOrDefault().MakeGeneric( genericTypes );
            }

            var result = hasTypes ? type.GetMethod( name, bindingFlags, null, parameterTypes, null )
                             	  : type.GetMethod( name, bindingFlags );
            if( result == null && bindingFlags.IsNotSet( Flags.DeclaredOnly ) )
            {
                if( type.BaseType != typeof(object) && type.BaseType != null )
                {
                    return type.BaseType.Method( name, parameterTypes, bindingFlags ).MakeGeneric( genericTypes );
                }
            }
        	bool hasSpecialFlags = bindingFlags.IsAnySet( Flags.ExcludeBackingMembers | Flags.ExcludeExplicitlyImplemented | Flags.ExcludeHiddenMembers );
            if( hasSpecialFlags )
            {
                var methods = new List<MethodInfo> { result }.Filter( bindingFlags );
                return (methods.Count > 0 ? methods[ 0 ] : null).MakeGeneric( genericTypes );
            }
            return result.MakeGeneric(genericTypes);
        }