using System; using System.Linq.Expressions; using System.Reflection; namespace CPF.Windows.Json.Deserialize { [ExpressionBuildType(DeserializeBuildTypeEnum.Collection)] internal class CollectionBuild : ExpressionJsonResolve { internal static BlockExpression Build(Type defindType, Type instanceType, Type convertType,Type arrayItemType) { /* //defind:IEnumerable new: List convert: List IEnumerable li = new List(); List list = (List)li; //defind:ArrayList new:ArrayList convert: IList/ArrayList ArrayList v = new ArrayList(); var df = (IList)v; */ Expression[] methodListCall = new Expression[9]; LabelTarget returnTarget = Expression.Label(defindType, "returnLable"); Expression ifReadNullOrArrayLeftReturnNull; if (!defindType.IsValueType) { /* if (reader.ReadNullOrArrayLeft()) return null; */ ifReadNullOrArrayLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrArrayLeft), Expression.Return(returnTarget, Expression.Constant(null, defindType))); } else { ifReadNullOrArrayLeftReturnNull = Expression.Call(ExpressionMembers.Reader,JsonReader._ReadArrayLeft); } methodListCall[0] = ifReadNullOrArrayLeftReturnNull; /* List<> list =new List<>(); */ NewExpression listCtor = Expression.New(instanceType); ParameterExpression list = Expression.Variable(defindType, "list"); methodListCall[1] = Expression.Assign(list, listCtor); /* if(reader.ReadBoolArrayRight) return list; */ methodListCall[2] = (Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolArrayRight), Expression.Return(returnTarget, list))); /* ICollection iCollec = (ICollection)list; iCollec.Add(ReadInt()) */ MethodInfo iCollecAdd = convertType.GetMethod("Add",BindingFlags.Public|BindingFlags.Instance); ParameterExpression iCollec = Expression.Variable(convertType, "iDic"); methodListCall[3] = Expression.Assign(iCollec, Expression.Convert(list, convertType)); /* int moveNext=1; */ methodListCall[4] = ExpressionMembers.MoveNextAssignOne; /* while(moveNext-->0) {} */ LabelTarget loopBreak = Expression.Label("loopBreak"); LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement, ReturnFunc(() => { Expression[] methodCall = new Expression[2]; /* list.Add(item); */ methodCall[0] = Expression.Call(iCollec, iCollecAdd, ExpressionMembers.GetMethodCall(arrayItemType)); /* if(reader.ReadBoolComma()==true) moveNext++; */ methodCall[1] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement; return Expression.Block(methodCall); ; }) , Expression.Break(loopBreak))); methodListCall[5] = Expression.Block(loopExpression, Expression.Label(loopBreak)); /* reader.ReadArrayRight() */ methodListCall[6] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayRight); /* return list; */ GotoExpression returnExpression = Expression.Return(returnTarget, list); LabelExpression returnLabel = Expression.Label(returnTarget, list); methodListCall[7] = returnExpression; methodListCall[8] = returnLabel; return Expression.Block(new[] { iCollec, list, ExpressionMembers.MoveNext }, methodListCall); } } }