74 lines
3.7 KiB
C#
74 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
|
|
namespace CPF.Windows.Json.Serializer
|
|
{
|
|
[ExpressionBuildType(SerializerBuildTypeEnum.IListGeneric)]
|
|
internal class IListGenericBuild : 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("IList`1").GetGenericArguments()[0];
|
|
else
|
|
arrayItemType = genericArguments[0];
|
|
}
|
|
|
|
List<Expression> methodCall = new List<Expression>();
|
|
|
|
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");
|
|
|
|
Type iListType = typeof(IList<>).MakeGenericType(arrayItemType);
|
|
ParameterExpression iList = Expression.Variable(iListType);
|
|
|
|
methodCall.Add(Expression.Assign(iList, Expression.Convert(instanceArg, iListType)));
|
|
|
|
ParameterExpression forVariable = Expression.Variable(typeof(int));
|
|
//Expression forExpression = ExpressionHelper.For(forVariable, Expression.LessThan(forVariable, Expression.MakeMemberAccess(instanceArg, type.IsArray ? type.GetProperty("Length") : type.GetProperty("Count"))), Expression.PostIncrementAssign(forVariable), Expression.Block(new[] { isFirst },
|
|
// Expression.IfThenElse(
|
|
// Expression.IsFalse(isFirst),
|
|
// Expression.Assign(isFirst, Expression.Constant(true)),
|
|
// ExpressionMembers.Append(",")
|
|
// ),
|
|
// ExpressionMembers.GetMethodCall(arrayItemType, type.IsArray ? Expression.ArrayAccess(instanceArg, forVariable) : Expression.MakeIndex(instanceArg, type.GetProperty("Item"), new[] { forVariable }))
|
|
// ));
|
|
|
|
Expression forExpression = ExpressionHelper.For(forVariable, Expression.LessThan(forVariable, Expression.MakeMemberAccess(instanceArg, type.IsArray ? type.GetProperty("Length") : type.GetProperty("Count"))), Expression.PostIncrementAssign(forVariable), Expression.Block(new[] { isFirst },
|
|
Expression.IfThenElse(
|
|
Expression.IsFalse(isFirst),
|
|
Expression.Assign(isFirst, Expression.Constant(true)),
|
|
ExpressionMembers.Append(",")
|
|
),
|
|
ExpressionMembers.GetMethodCall(arrayItemType, Expression.MakeIndex(iList, iListType.GetProperty("Item"), new[] { forVariable }))
|
|
));
|
|
|
|
|
|
methodCall.Add(forExpression);
|
|
methodCall.Add(ExpressionMembers.Append("]"));
|
|
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop);
|
|
methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
|
return Expression.Block(new[] { iList }, methodCall);
|
|
|
|
}
|
|
}
|
|
}
|