using System; using System.Collections.Generic; using System.Linq.Expressions; namespace CPF.Windows.Json.Serializer { [ExpressionBuildType(SerializerBuildTypeEnum.IEnumerableGeneric)] internal class IEnumerableGenericBuild : ExpressionJsonFormatter { internal static Expression Build(Type type, ParameterExpression instanceArg) { Type arrayItemType = type.GetElementType(); if (arrayItemType == null) { Type[] genericArguments = type.GetGenericArguments(); if (genericArguments.Length == 0) arrayItemType = type.GetInterface("IEnumerable`1").GetGenericArguments()[0]; else arrayItemType = genericArguments[0]; } List methodCall = new List(); if (!type.IsValueType) { ConditionalExpression ifNullAppendNull = Expression.IfThen( Expression.Equal(instanceArg, Expression.Constant(null,type)), Expression.Block(ExpressionMembers.Append("null"), Expression.Return(ExpressionMembers.ReturnLable) )); methodCall.Add(ifNullAppendNull); } methodCall.Add(ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.Array)); methodCall.Add(ExpressionMembers.Append("[")); ParameterExpression isFirst = Expression.Variable(typeof(bool), "isFirst"); Expression foreachs = ExpressionHelper.ForEach(instanceArg, Expression.Parameter(arrayItemType, "loopVar"), item => Expression.Block(new[] { isFirst }, Expression.IfThenElse( Expression.IsFalse(isFirst), Expression.Assign(isFirst, Expression.Constant(true)), ExpressionMembers.Append(",") ), ExpressionMembers.GetMethodCall(arrayItemType, item) )); methodCall.Add(foreachs); methodCall.Add(ExpressionMembers.Append("]")); methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop); methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable)); return Expression.Block(methodCall); } } }