/// <summary>
        /// used while generating a boxed value type for a native cls type, i.e.
        /// no attributes other than a single IdlSequenceAttribute is needed on boxed field.
        /// </summary>
        private FieldBuilder DefineBoxedField(TypeBuilder boxBuilder, Type boxedType,
                                              BoxedValueRuntimeTypeGenerator gen)
        {
            Type fieldType = boxedType;

            if (boxedType.IsArray)
            {
                if (boxedType.GetElementType().IsArray)
                {
                    // recursive boxing needed: fieldType is an array of boxed values
                    fieldType = Array.CreateInstance(gen.GetOrCreateBoxedTypeForArray(boxedType.GetElementType()), 0).GetType();
                }
                else
                {
                    // last step, can box directly
                    fieldType = boxedType;
                }
            }
            // create the field for the boxed value
            FieldBuilder fieldBuild = boxBuilder.DefineField("m_val", fieldType, FieldAttributes.Private);

            if (boxedType.IsArray)
            {
                CustomAttributeBuilder attrBuilder = (new IdlSequenceAttribute(0)).CreateAttributeBuilder();
                fieldBuild.SetCustomAttribute(attrBuilder);
            }
            return(fieldBuild);
        }
        /// <summary>define the box-Type for the CLS arrayType</summary>
        private void DefineBoxedTypeForCLSArray(TypeBuilder boxBuilder, Type arrayType,
                                                BoxedValueRuntimeTypeGenerator gen)
        {
            IlEmitHelper.GetSingleton().AddSerializableAttribute(boxBuilder);
            // add the field for the boxed value content
            FieldBuilder valField = DefineBoxedField(boxBuilder, arrayType, gen);

            // define getValue method
            DefineGetValue(boxBuilder, valField);
            // define getBoxed type methods:
            DefineGetBoxedType(boxBuilder, valField);
            DefineGetBoxedTypeAttributes(boxBuilder, valField);
            DefineGetFirstNonBoxedType(boxBuilder, arrayType);
            DefineGetFirstNonBoxedTypeName(boxBuilder, arrayType);
            // define the constructors
            DefineEmptyDefaultConstr(boxBuilder);
            // define the constructor which sets the valField directly
            DefineAssignConstr(boxBuilder, valField);
            // define the constructor which transforms a .NET array to the form assignable to the valField, if types are different
            if (!valField.FieldType.Equals(arrayType))
            {
                // need a constructor which transforms instance before assigning
                DefineTransformAndAssignConstrForArray(boxBuilder, valField, arrayType);
            }
        }
        /// <summary>create the boxed value type(s) for a .NET arrayType</summary>
        internal TypeBuilder CreateBoxedTypeForArray(Type arrayType, ModuleBuilder modBuilder,
                                                     BoxedValueRuntimeTypeGenerator gen)
        {
            // create the boxed value type(s) for the array
            string      boxedTypeFullName = CreateBoxedArrayFullTypeName(arrayType);
            TypeBuilder boxBuilder        = modBuilder.DefineType(boxedTypeFullName,
                                                                  TypeAttributes.Class | TypeAttributes.Public,
                                                                  ReflectionHelper.BoxedValueBaseType);

            DefineBoxedTypeForCLSArray(boxBuilder, arrayType, gen);
            return(boxBuilder);
        }
 /// <summary>
 /// used while generating a boxed value type for a native cls type, i.e.
 /// no attributes other than a single IdlSequenceAttribute is needed on boxed field.
 /// </summary>
 private FieldBuilder DefineBoxedField(TypeBuilder boxBuilder, Type boxedType,
                                       BoxedValueRuntimeTypeGenerator gen) {
     Type fieldType = boxedType; 
     if (boxedType.IsArray) {
         if (boxedType.GetElementType().IsArray) {
             // recursive boxing needed: fieldType is an array of boxed values
             fieldType = Array.CreateInstance(gen.GetOrCreateBoxedTypeForArray(boxedType.GetElementType()), 0).GetType();
         } else {
             // last step, can box directly
             fieldType = boxedType;
         }
     }
     // create the field for the boxed value
     FieldBuilder fieldBuild = boxBuilder.DefineField("m_val", fieldType, FieldAttributes.Private);
     if (boxedType.IsArray) {
         CustomAttributeBuilder attrBuilder = (new IdlSequenceAttribute(0)).CreateAttributeBuilder();
         fieldBuild.SetCustomAttribute(attrBuilder);
     }
     return fieldBuild;
 }
 /// <summary>define the box-Type for the CLS arrayType</summary>
 private void DefineBoxedTypeForCLSArray(TypeBuilder boxBuilder, Type arrayType,
                                         BoxedValueRuntimeTypeGenerator gen) {            
     IlEmitHelper.GetSingleton().AddSerializableAttribute(boxBuilder);
     // add the field for the boxed value content
     FieldBuilder valField = DefineBoxedField(boxBuilder, arrayType, gen);
     // define getValue method
     DefineGetValue(boxBuilder, valField);
     // define getBoxed type methods:
     DefineGetBoxedType(boxBuilder, valField);
     DefineGetBoxedTypeAttributes(boxBuilder, valField);
     DefineGetFirstNonBoxedType(boxBuilder, arrayType);
     DefineGetFirstNonBoxedTypeName(boxBuilder, arrayType);
     // define the constructors
     DefineEmptyDefaultConstr(boxBuilder);
     // define the constructor which sets the valField directly
     DefineAssignConstr(boxBuilder, valField);
     // define the constructor which transforms a .NET array to the form assignable to the valField, if types are different
     if (!valField.FieldType.Equals(arrayType)) {
         // need a constructor which transforms instance before assigning
         DefineTransformAndAssignConstrForArray(boxBuilder, valField, arrayType);
     }    
 }
 /// <summary>create the boxed value type(s) for a .NET arrayType</summary>
 internal TypeBuilder CreateBoxedTypeForArray(Type arrayType, ModuleBuilder modBuilder,
                                              BoxedValueRuntimeTypeGenerator gen) {
     // create the boxed value type(s) for the array
     string boxedTypeFullName = CreateBoxedArrayFullTypeName(arrayType);
     TypeBuilder boxBuilder = modBuilder.DefineType(boxedTypeFullName,
                                                    TypeAttributes.Class | TypeAttributes.Public,
                                                    ReflectionHelper.BoxedValueBaseType);
     DefineBoxedTypeForCLSArray(boxBuilder, arrayType, gen);
     return boxBuilder;
 }