Пример #1
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);
        }