CK.Reflection.TypeBuilderExtension.DefinePassThroughConstructors C# (CSharp) Method

DefinePassThroughConstructors() public static method

Creates constructors that relay calls to public and protected constructors in the base class.
public static DefinePassThroughConstructors ( this @this, MethodAttributes?>.Func baseConstructorfilter = null, Func constructorAttributesFilter = null, Func parameterAttributesFilter = null ) : void
@this this
baseConstructorfilter MethodAttributes?>.Func /// Optional predicate used to filter constructors that must be implemented and set its . /// When this function returns null, the constructor is not implemented, otherwise it can return the baseConstructor's Attribute. /// When null, all public and protected constructors are replicated with the same access (public or protected). ///
constructorAttributesFilter Func /// Optional predicate used to filter constructors' attributes. /// When null, all attributes are redefined. ///
parameterAttributesFilter Func /// Optional predicate used to filter constructors' arguments' attributes. /// When null, all attributes are redefined. ///
return void
        public static void DefinePassThroughConstructors( this TypeBuilder @this,
                                                            Func<ConstructorInfo,MethodAttributes?> baseConstructorfilter = null,
                                                            Func<ConstructorInfo, CustomAttributeData, bool> constructorAttributesFilter = null,
                                                            Func<ParameterInfo, CustomAttributeData, bool> parameterAttributesFilter = null )
        {
            Type baseType = @this.BaseType;
            foreach( var baseCtor in baseType.GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ) )
            {
                if( baseCtor.IsPrivate ) continue;
                MethodAttributes? newCtorAttr = baseCtor.Attributes;
                if( baseConstructorfilter != null && !(newCtorAttr = baseConstructorfilter( baseCtor )).HasValue ) continue;
                var parameters = baseCtor.GetParameters();
                if( parameters.Length == 0 ) @this.DefineDefaultConstructor( newCtorAttr.Value );
                else
                {
                    Type[] parameterTypes = ReflectionHelper.CreateParametersType( parameters );
                    // REVIEW: Type.EmptyTypes replaces GetRequiredCustomModifiers and GetOptionalCustomModifiers 
                    Type[][] requiredCustomModifiers =  parameters.Select( p => Type.EmptyTypes ).ToArray();
                    Type[][] optionalCustomModifiers = parameters.Select( p => Type.EmptyTypes ).ToArray();

                    var ctor = @this.DefineConstructor( newCtorAttr.Value, baseCtor.CallingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers );
                    for( var i = 0; i < parameters.Length; ++i )
                    {
                        ParameterInfo parameter = parameters[i];
                        ParameterBuilder pBuilder = ctor.DefineParameter( i + 1, parameter.Attributes, parameter.Name );
                        if( (parameter.Attributes & ParameterAttributes.HasDefault) != 0 )
                        {
                            pBuilder.SetConstant( parameter.DefaultValue );
                        }
                        if( parameterAttributesFilter != null )
                        {
                            ReflectionHelper.GenerateCustomAttributeBuilder( parameter.CustomAttributes, pBuilder.SetCustomAttribute, a => parameterAttributesFilter( parameter, a ) );
                        }
                        else
                        {
                            ReflectionHelper.GenerateCustomAttributeBuilder( parameter.CustomAttributes, pBuilder.SetCustomAttribute );
                        }
                    }
                    if( constructorAttributesFilter != null )
                    {
                        ReflectionHelper.GenerateCustomAttributeBuilder( baseCtor.CustomAttributes, ctor.SetCustomAttribute, a => constructorAttributesFilter( baseCtor, a ) );
                    }
                    else
                    {
                        ReflectionHelper.GenerateCustomAttributeBuilder( baseCtor.CustomAttributes, ctor.SetCustomAttribute );
                    }
                    var g = ctor.GetILGenerator();
                    g.RepushActualParameters( true, parameters.Length + 1 );
                    g.Emit( OpCodes.Call, baseCtor );
                    g.Emit( OpCodes.Ret );
                }
            }
        }
TypeBuilderExtension