public CollectionMembers(ExtendedType collectionType) { ArrayContainerTypeInfo arrayTypeInfo; if (collectionType.TryGetArrayTypeInfo(out arrayTypeInfo)) { if (arrayTypeInfo.Ranks > 3) throw new NotSupportedException("The serialization engine is limited to 3 ranks in arrays"); if (arrayTypeInfo.Ranks == 3) { var baseType = typeof (ICollection<>); ElementType = baseType.MakeGenericType(baseType.MakeGenericType(arrayTypeInfo.ElementType)); ToArray = typeof (ArrayProvider).GetMethod("To3DArray").MakeGenericMethod(arrayTypeInfo.ElementType); } else if (arrayTypeInfo.Ranks == 2) { ElementType = typeof (ICollection<>).MakeGenericType(arrayTypeInfo.ElementType); ToArray = typeof(ArrayProvider).GetMethod("To2DArray").MakeGenericMethod(arrayTypeInfo.ElementType); } else { ElementType = arrayTypeInfo.ElementType; ToArray = typeof(ArrayProvider).GetMethod("ToArray").MakeGenericMethod(arrayTypeInfo.ElementType); } } else { ElementType = collectionType.Container.AsCollection().ElementType; } ElementTypeExt = ElementType.Extend(); VariableType = typeof (ICollection<>).MakeGenericType(ElementType); Add = VariableType.GetMethod("Add", new[] { ElementType }); var instanceType = collectionType.Ref.IsInterface || collectionType.Ref.IsArray ? typeof(List<>).MakeGenericType(ElementType) : collectionType.Ref; Constructor = instanceType.GetConstructor(Type.EmptyTypes); if (Constructor == null) throw InvalidGraphException.NoParameterLessConstructor(collectionType.Ref); }
private void GenerateEnumerateCollectionContentCode(ExtendedType target, ILCodeParameter collectionParameter) { ArrayContainerTypeInfo arrayTypeInfo; if (target.TryGetArrayTypeInfo(out arrayTypeInfo) && arrayTypeInfo.Ranks > 1) { if (arrayTypeInfo.Ranks > 3) throw new NotSupportedException("The serialization engine is limited to 3 ranks in arrays"); _il.Snippets.ForLoop(0, new CallMethodILCode(collectionParameter, Members.ArrayGetLength, 0), 1, r0 => { _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorVisit, collectionParameter, Members.VisitArgsCollectionInCollection); _il.Snippets.ForLoop(0, new CallMethodILCode(collectionParameter, Members.ArrayGetLength, 1), 1, r1 => { if (arrayTypeInfo.Ranks > 2) { _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorVisit, collectionParameter, Members.VisitArgsCollectionInCollection); _il.Snippets.ForLoop(0, new CallMethodILCode(collectionParameter, Members.ArrayGetLength, 1), 1, r2 => GenerateEnumerateContentCode( new CallMethodILCode(collectionParameter, target.Ref.GetMethod("Get"), r0, r1, r2), LevelType.CollectionItem)); _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection); } else { GenerateEnumerateContentCode(new CallMethodILCode(collectionParameter, target.Ref.GetMethod("Get"), r0, r1), LevelType.CollectionItem); } }); _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection); }); } else { var part = new ILEnumerateCode(collectionParameter, (il, it) => GenerateEnumerateContentCode(it, LevelType.CollectionItem)); _il.Generate(part); } }