public override object Serialize(IDesignerSerializationManager manager, object value) { if (manager == null) { throw new ArgumentNullException("manager"); } if (value == null) { throw new ArgumentNullException("value"); } object obj2 = null; using (CodeDomSerializerBase.TraceScope("CollectionCodeDomSerializer::Serialize")) { CodeExpression expression; ExpressionContext context = manager.Context[typeof(ExpressionContext)] as ExpressionContext; PropertyDescriptor descriptor = manager.Context[typeof(PropertyDescriptor)] as PropertyDescriptor; if (((context != null) && (context.PresetValue == value)) && ((descriptor != null) && (descriptor.PropertyType == context.ExpressionType))) { expression = context.Expression; } else { expression = null; context = null; descriptor = null; } ICollection is2 = value as ICollection; if (is2 == null) { return(obj2); } ICollection valuesToSerialize = is2; InheritedPropertyDescriptor descriptor2 = descriptor as InheritedPropertyDescriptor; Type c = (context == null) ? is2.GetType() : context.ExpressionType; bool flag = typeof(Array).IsAssignableFrom(c); if ((expression == null) && !flag) { bool flag2; expression = base.SerializeCreationExpression(manager, is2, out flag2); if (flag2) { return(expression); } } if ((expression == null) && !flag) { return(obj2); } if ((descriptor2 != null) && !flag) { valuesToSerialize = this.GetCollectionDelta(descriptor2.OriginalValue as ICollection, is2); } obj2 = this.SerializeCollection(manager, expression, c, is2, valuesToSerialize); if ((expression == null) || !this.ShouldClearCollection(manager, is2)) { return(obj2); } CodeStatementCollection statements = obj2 as CodeStatementCollection; if ((is2.Count > 0) && ((obj2 == null) || ((statements != null) && (statements.Count == 0)))) { return(null); } if (statements == null) { statements = new CodeStatementCollection(); CodeStatement statement = obj2 as CodeStatement; if (statement != null) { statements.Add(statement); } obj2 = statements; } if (statements != null) { CodeMethodInvokeExpression expression2 = new CodeMethodInvokeExpression(expression, "Clear", new CodeExpression[0]); CodeExpressionStatement statement2 = new CodeExpressionStatement(expression2); statements.Insert(0, statement2); } } return(obj2); }
/// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeViaAdd"]/*' /> /// <devdoc> /// Serializes the given collection by creating multiple calls to an Add method. /// </devdoc> private object SerializeViaAdd( IDesignerSerializationManager manager, CodePropertyReferenceExpression propRef, ICollection collection, MethodInfo addMethod, ParameterInfo parameter, object targetObject) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeViaAdd"); Debug.Indent(); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Collection: " + collection.GetType().Name); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Elements: " + collection.Count.ToString()); // Here we need to invoke Add once for each and every item in the collection. We can re-use the property // reference and method reference, but we will need to recreate the invoke statement each time. // CodeStatementCollection statements = new CodeStatementCollection(); CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression(propRef, addMethod.Name); MethodInfo clearMethod = collection.GetType().GetMethod("Clear", new Type[0]); if (clearMethod != null) { PropertyDescriptor clearProp = manager.Properties["ClearCollections"]; if (clearProp != null) { // insert code here to clear the collecion... // statements.Add(new CodeMethodInvokeExpression(propRef, "Clear")); } } bool isTargetInherited = false; InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor; if (inheritedDesc != null) { isTargetInherited = true; collection = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, collection); if (collection.Count == 0) { Debug.Unindent(); return(statements); } } foreach (object o in collection) { // If this object is being privately inherited, it cannot be inside // this collection. // bool genCode = !(o is IComponent); if (!genCode) { InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(o)[typeof(InheritanceAttribute)]; if (ia != null) { if (ia.InheritanceLevel == InheritanceLevel.InheritedReadOnly) { genCode = false; } else if (ia.InheritanceLevel == InheritanceLevel.Inherited && isTargetInherited) { genCode = false; } else { genCode = true; } } else { genCode = true; } } if (genCode) { CodeMethodInvokeExpression statement = new CodeMethodInvokeExpression(); statement.Method = methodRef; CodeValueExpression codeValue = new CodeValueExpression(null, o, parameter.ParameterType); manager.Context.Push(codeValue); CodeExpression serializedObj = null; try { serializedObj = SerializeToExpression(manager, o); } finally { manager.Context.Pop(); } if (serializedObj != null) { statement.Parameters.Add(serializedObj); statements.Add(statement); } } } Debug.Unindent(); return(statements); }
/// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeViaAddRange"]/*' /> /// <devdoc> /// Serializes the given collection by creating an array and passing it to the AddRange method. /// </devdoc> private object SerializeViaAddRange( IDesignerSerializationManager manager, CodePropertyReferenceExpression propRef, ICollection collection, MethodInfo addRangeMethod, ParameterInfo parameter, object targetObject) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeViaAddRange"); Debug.Indent(); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Collection: " + collection.GetType().Name); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Elements: " + collection.Count.ToString()); CodeStatementCollection statements = new CodeStatementCollection(); MethodInfo clearMethod = collection.GetType().GetMethod("Clear", new Type[0]); if (clearMethod != null) { PropertyDescriptor clearProp = manager.Properties["ClearCollections"]; if (clearProp != null && clearProp.PropertyType == typeof(bool) && ((bool)clearProp.GetValue(manager) == true)) { // insert code here to clear the collecion... // statements.Add(new CodeMethodInvokeExpression(propRef, "Clear")); } } if (collection.Count == 0) { Debug.Unindent(); return(statements); } // We must walk the collection looking for privately inherited objects. If we find them, // we need to exclude them from the array. // ArrayList arrayList = new ArrayList(collection.Count); bool isTargetInherited = false; InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor; if (inheritedDesc != null) { isTargetInherited = true; collection = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, collection); if (collection.Count == 0) { Debug.Unindent(); return(statements); } } CodeValueExpression codeValue = new CodeValueExpression(null, collection, parameter.ParameterType.GetElementType()); manager.Context.Push(codeValue); try { foreach (object o in collection) { // If this object is being privately inherited, it cannot be inside // this collection. // bool genCode = !(o is IComponent); if (!genCode) { InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(o)[typeof(InheritanceAttribute)]; if (ia != null) { if (ia.InheritanceLevel == InheritanceLevel.InheritedReadOnly) { genCode = false; } else if (ia.InheritanceLevel == InheritanceLevel.Inherited && isTargetInherited) { genCode = false; } else { genCode = true; } } else { genCode = true; } } if (genCode) { CodeExpression exp = SerializeToExpression(manager, o); if (exp != null) { arrayList.Add(exp); } } } } finally { manager.Context.Pop(); } if (arrayList.Count > 0) { // Now convert the array list into an array create expression. // CodeTypeReference elementTypeRef = new CodeTypeReference(parameter.ParameterType.GetElementType()); // Now create an ArrayCreateExpression, and fill its initializers. // CodeArrayCreateExpression arrayCreate = new CodeArrayCreateExpression(); arrayCreate.CreateType = elementTypeRef; foreach (CodeExpression exp in arrayList) { arrayCreate.Initializers.Add(exp); } CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression(propRef, addRangeMethod.Name); CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); methodInvoke.Method = methodRef; methodInvoke.Parameters.Add(arrayCreate); statements.Add(new CodeExpressionStatement(methodInvoke)); } Debug.Unindent(); return(statements); }
/// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeArray"]/*' /> /// <devdoc> /// Serializes the given array. /// </devdoc> private object SerializeArray(IDesignerSerializationManager manager, CodePropertyReferenceExpression propRef, Type asType, Array array, object targetObject) { object result = null; Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeArray"); Debug.Indent(); if (array.Rank != 1) { Debug.WriteLineIf(traceSerialization.TraceError, "*** Cannot serialize arrays with rank > 1. ***"); manager.ReportError(SR.GetString(SR.SerializerInvalidArrayRank, array.Rank.ToString())); } else { // For an array, we need an array create expression. First, get the array type // Type elementType = null; if (asType != null) { elementType = asType; } else { elementType = array.GetType().GetElementType(); } CodeTypeReference elementTypeRef = new CodeTypeReference(elementType); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Array type: " + elementType.Name); Debug.WriteLineIf(traceSerialization.TraceVerbose, "Length:" + array.Length.ToString()); // Now create an ArrayCreateExpression, and fill its initializers. // CodeArrayCreateExpression arrayCreate = new CodeArrayCreateExpression(); arrayCreate.CreateType = elementTypeRef; bool arrayOk = true; ICollection collection = array; bool isTargetInherited = false; IComponent comp = targetObject as IComponent; if (comp != null) { InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(comp)[typeof(InheritanceAttribute)]; isTargetInherited = (ia != null && ia.InheritanceLevel == InheritanceLevel.Inherited); } if (isTargetInherited) { InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor; if (inheritedDesc != null) { collection = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, array); } } CodeValueExpression codeValue = new CodeValueExpression(null, collection, elementType); manager.Context.Push(codeValue); try { foreach (object o in collection) { // If this object is being privately inherited, it cannot be inside // this collection. Since we're writing an entire array here, we // cannot write any of it. // if (o is IComponent && TypeDescriptor.GetAttributes(o).Contains(InheritanceAttribute.InheritedReadOnly)) { arrayOk = false; break; } object expression = SerializeToExpression(manager, o); if (expression is CodeExpression) { arrayCreate.Initializers.Add((CodeExpression)expression); } else { arrayOk = false; break; } } } finally { manager.Context.Pop(); } // if we weren't given a property, we're done. Otherwise, we must create an assign statement for // the property. // if (arrayOk) { if (propRef != null) { result = new CodeAssignStatement(propRef, arrayCreate); } else { result = arrayCreate; } } } Debug.Unindent(); return(result); }