using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using System.Text; namespace CPF.Windows.Json.Serializer { [ExpressionBuildType(SerializerBuildTypeEnum.KeyValueObject)] internal class KeyValueObjectBuild : ExpressionJsonFormatter { internal static Expression Build(Type type, ParameterExpression instanceArg) { List methodCall = new List(); if (!type.IsValueType) { ConditionalExpression ifParaIsNullAppendNull = Expression.IfThen(Expression.Equal(instanceArg, Expression.Constant(null, type)), Expression.Block( ExpressionMembers.Append("null"), Expression.Return(ExpressionMembers.ReturnLable) )); methodCall.Add(ifParaIsNullAppendNull);//add Expression isIgnoreSelfRefernceModule = ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.CustomType); methodCall.Add(isIgnoreSelfRefernceModule);//add } methodCall.Add(ExpressionMembers.WriteLeft); var elements = type.GetModelMembers(ReadMemberStateEnum.CanRead); bool hasIgnoreDefaultValueAttribute = false; for (int i = 0; i < elements.Count; i++) { var item = elements[i]; //valueformat ValueFormatAttribute valueformat = item.Value.MemberInfo.GetCustomAttribute() ?? item.Value.MemberInfo.DeclaringType.GetCustomAttribute(); //IgnoreDefaultValue IgnoreDefaultValueAttribute ignoreDefaultValue = item.Value.MemberInfo.GetCustomAttribute() ?? item.Value.MemberInfo.DeclaringType.GetCustomAttribute(); if (ignoreDefaultValue != null) hasIgnoreDefaultValueAttribute = true; //if (!(m.Name == null && handler.option.IsIgnoreNull))//0 MemberExpression mName = Expression.MakeMemberAccess(instanceArg, item.Value.MemberInfo); // if (option1.IsFirstLower) string lowerName = item.Key.Substring(0, 1).ToLower() + item.Key.Substring(1); string upperName = item.Key.Substring(0, 1).ToUpper() + item.Key.Substring(1); /* ignoreKeys == null || ignoreKeys.count() == 0 || ignoreKeys.Contains(name)==false */ BinaryExpression ignoreKeysJudge = Expression.OrElse( ExpressionMembers.IgnoreKeysIsNull, Expression.OrElse( ExpressionMembers.IgnoreKeysCountIsZero, Expression.Equal( Expression.Call(ExpressionMembers.IgnoreKeys, typeof(List).GetMethod("Contains"), Expression.Constant(item.Key)) , Expression.Constant(false)) )); /* (ignoreKeys == null || ignoreKeys.count() == 0 || ignoreKeys.Contains(name)==false) && ( m!=default(m) ) */ if (ignoreDefaultValue != null) ignoreKeysJudge = Expression.AndAlso(ignoreKeysJudge, Expression.NotEqual(mName, Expression.Constant(item.Value.Type.GetDefaultValue(), item.Value.Type))); /* if(option.keyformat!=null) $handler.WriteString("\""); $handler.WriteString(option.keyformat.invoke(string)); append("\":") else { switch(JsonCharacterRead) { case None: AppendKey() case InitialUpper: .. case InitialLower: .. } } }; */ Expression writeKey = Expression.IfThenElse(Expression.NotEqual(ExpressionMembers.GlobalKeyFormat, Expression.Constant(null, JsonSerializerOption._GlobalKeyFormat.FieldType)), Expression.Block( ExpressionMembers.Append("\""), Expression.Call(ExpressionMembers.WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Call(ExpressionMembers.GlobalKeyFormat, JsonSerializerOption._GlobalKeyFormatInvoke, Expression.Constant(item.Key), Expression.Constant(type, typeof(Type)), ExpressionMembers.HandlerArg) ), ExpressionMembers.Append("\":") ), Expression.Switch(typeof(void), ExpressionMembers.JsonCharacterRead, null, null, Expression.SwitchCase(ExpressionMembers.AppendKey(item.Key), Expression.Constant(JsonCharacterReadStateEnum.None, typeof(JsonCharacterReadStateEnum))), Expression.SwitchCase(ExpressionMembers.AppendKey(upperName), Expression.Constant(JsonCharacterReadStateEnum.InitialUpper, typeof(JsonCharacterReadStateEnum))), Expression.SwitchCase(ExpressionMembers.AppendKey(lowerName), Expression.Constant(JsonCharacterReadStateEnum.InitialLower, typeof(JsonCharacterReadStateEnum))) ) ); /* string afterValueFormat= valueformat.WriteValueFormat( model.Name,hander out isValueFormat) if(isValueFormat) sb.append(afterValueFormat) else WriteValue(model.Name,handler) */ Expression writeValue; if (valueformat != null) { writeValue = Expression.Block( Expression.NotEqual(ExpressionMembers.GlobalValueFormat, Expression.Constant(null, JsonSerializerOption._GlobalValueFormat.FieldType)), Expression.Assign(ExpressionMembers.AfterValueFormat, Expression.Call(Expression.Constant(valueformat, typeof(ValueFormatAttribute)), ValueFormatAttribute._WriteValueFormat, Expression.Convert(mName, typeof(object)), Expression.Constant(item.Value.Type, typeof(Type)), ExpressionMembers.HandlerArg, ExpressionMembers.IsValueFormat)), Expression.IfThenElse(Expression.IsTrue(ExpressionMembers.IsValueFormat), ExpressionMembers.Append(ExpressionMembers.AfterValueFormat), ExpressionMembers.GetMethodCall(item.Value.Type, mName)) ); } else { /* if( option.GlobalValueFormat!=null){ string afterValueFormat= option.GlobalValueFormat.Invoke( model.Name,hander out isValueFormat) if(isValueFormat) sb.append(afterValueFormat) else WriteValue(model.Name,handler) } else { WriteValue(model.Name,handler) } */ writeValue = Expression.IfThenElse( Expression.NotEqual(ExpressionMembers.GlobalValueFormat, Expression.Constant(null, JsonSerializerOption._GlobalValueFormat.FieldType)), Expression.Block( Expression.Assign(ExpressionMembers.AfterValueFormat, Expression.Call(ExpressionMembers.GlobalValueFormat, JsonSerializerOption._GlobalValueFormatInvoke, Expression.Convert(mName, typeof(object)), Expression.Constant(item.Value.Type, typeof(Type)), ExpressionMembers.HandlerArg, ExpressionMembers.IsValueFormat)), Expression.IfThenElse(Expression.IsTrue(ExpressionMembers.IsValueFormat), ExpressionMembers.Append(ExpressionMembers.AfterValueFormat), ExpressionMembers.GetMethodCall(item.Value.Type, mName)) ), ExpressionMembers.GetMethodCall(item.Value.Type, mName) ); } Expression trunk = Expression.Block(writeKey, writeValue); // json.Append(","); if (i != elements.Count - 1) trunk = Expression.Block(trunk, ExpressionMembers.WriteComma); if (!item.Value.Type.IsValueType || (item.Value.Type.IsGenericType && item.Value.Type.GetGenericTypeDefinition() == typeof(Nullable<>))) { BinaryExpression mNameIsNull = Expression.Equal(mName, Expression.Constant(null)); //if(!null&&isgorenull) trunk = Expression.IfThen(Expression.IsFalse(Expression.And(mNameIsNull, ExpressionMembers.IgnoreValueNullIsTrue)), trunk); } // trunk = Expression.IfThen(ignoreKeysJudge, trunk);//忽略key methodCall.Add(trunk); } // //if ( ignoreValueNull == true || ignoreKeys!=null ) ==> RemoveLastComma() var IgnoreValueNullIsTrueOrIgnoreKeysNotEqureNullRemoveLastComma = Expression.IfThen( Expression.OrElse(ExpressionMembers.IgnoreValueNullIsTrue, ExpressionMembers.IgnoreKeysIsNotNull), ExpressionMembers.RemoveLastComma() ); methodCall.Add(hasIgnoreDefaultValueAttribute? (Expression)ExpressionMembers.RemoveLastComma():IgnoreValueNullIsTrueOrIgnoreKeysNotEqureNullRemoveLastComma); methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsRemoveDeleteComma); methodCall.Add(ExpressionMembers.WriteRight); methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop); methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable)); return Expression.Block(new[] { ExpressionMembers.AfterValueFormat, ExpressionMembers.IsValueFormat }, methodCall); } } }