/// <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); } }
private void BeginType() { // add IdlUnion attribute m_builder.SetCustomAttribute(new IdlUnionAttribute().CreateAttributeBuilder()); IlEmitHelper.GetSingleton().AddSerializableAttribute(m_builder); AddTypeField(); AddInitalizedFieldAndProperty(); AddStaticConstructor(); // add the static constructor }
/// <summary>define the box-Type for the boxed type other than a CLS array</summary> private void DefineBoxedType(TypeBuilder boxBuilder, Type boxedType, CustomAttributeBuilder[] attrsOnBoxedType) { IlEmitHelper.GetSingleton().AddSerializableAttribute(boxBuilder); // add the field for the boxed value content FieldBuilder valField = DefineBoxedField(boxBuilder, boxedType, attrsOnBoxedType); // define getValue method DefineGetValue(boxBuilder, valField); // define getBoxed type methods: DefineGetBoxedType(boxBuilder, valField); DefineGetBoxedTypeAttributes(boxBuilder, valField); Type fullUnboxed = boxedType; if ((fullUnboxed.IsArray) && (fullUnboxed.GetElementType().IsSubclassOf(ReflectionHelper.BoxedValueBaseType))) { // call GetFirstNonBoxed static method on element type try { Type unboxedElemType = (Type)fullUnboxed.GetElementType().InvokeMember( BoxedValueBase.GET_FIRST_NONBOXED_TYPE_METHODNAME, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly, null, null, new object[0]); Array dummyArray = Array.CreateInstance(unboxedElemType, 0); fullUnboxed = dummyArray.GetType(); } catch (Exception) { // invalid type found in boxed value creation: " + fullUnboxed throw new INTERNAL(10045, CompletionStatus.Completed_MayBe); } } else if (fullUnboxed.IsSubclassOf(ReflectionHelper.BoxedValueBaseType)) { // call GetFirstNonBoxed static method on type try { fullUnboxed = (Type)fullUnboxed.InvokeMember( BoxedValueBase.GET_FIRST_NONBOXED_TYPE_METHODNAME, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly, null, null, new object[0]); } catch (Exception) { // invalid type found: fullUnboxed, // static method missing or not callable: // BoxedValueBase.GET_FIRST_NONBOXED_TYPE_METHODNAME throw new INTERNAL(10044, CompletionStatus.Completed_MayBe); } } if ((fullUnboxed.IsArray) && (fullUnboxed.GetElementType().IsArray)) { // add a constructor, which takes a CLS array (with an element type which is also an array) and creates the boxed value type for the instance // for arrays with an element type, which is not an array, such a constructor already exists DefineTransformAndAssignConstrForArray(boxBuilder, valField, fullUnboxed); } if ((boxedType.IsArray) && (!boxedType.GetElementType().IsArray) && (boxedType.GetElementType().IsSubclassOf(ReflectionHelper.BoxedValueBaseType))) { Type boxedElemType; try { // get the type boxed in the element boxedElemType = (Type)boxedType.GetElementType().InvokeMember( BoxedValueBase.GET_BOXED_TYPE_METHOD_NAME, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly, null, null, new object[0]); } catch (Exception) { // invalid type found: boxedType.GetElementType(), // static method missing or not callable: // BoxedValueBase.GET_BOXED_TYPE_METHOD_NAME throw new INTERNAL(10044, CompletionStatus.Completed_MayBe); } if (!boxedElemType.IsArray) { // The boxed type which should be defined, has type of the following form boxed: // a sequence of BoxedValues, but these boxed values do not box arrays itself // for this boxed type an additional transform constructor is needed, which boxes the elements // of the sequence Array boxedInnerArray = Array.CreateInstance(boxedElemType, 0); DefineTransformAndAssignConstrForArray(boxBuilder, valField, boxedInnerArray.GetType()); } } if ((!boxedType.IsArray) && (boxedType.IsSubclassOf(ReflectionHelper.BoxedValueBaseType))) { // The boxed value type boxes another boxed value type --> need a transform constructor, // which takes an unboxed value and boxes it, before assigning it to the field // TODO: implement this throw new NO_IMPLEMENT(12345, CompletionStatus.Completed_MayBe); } DefineGetFirstNonBoxedType(boxBuilder, fullUnboxed); DefineGetFirstNonBoxedTypeName(boxBuilder, fullUnboxed); // define the constructors DefineEmptyDefaultConstr(boxBuilder); // define the constructor which sets the valField directly DefineAssignConstr(boxBuilder, valField); }