/// <summary> /// Deserialize an <see cref="Expression"/>. /// </summary> /// <param name="json">The fragment to deserialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The deserialized <see cref="Expression"/>.</returns> public Expression Deserialize( JsonElement json, SerializationState state) { if (json.ValueKind == JsonValueKind.Null) { return(null); } if (!json.TryGetProperty(nameof(Type), out JsonElement typeElem)) { return(null); } if (typeElem.ValueKind == JsonValueKind.Null) { return(null); } var type = (ExpressionType)typeElem.GetInt32(); if (serializers.ContainsKey(type)) { return(serializers[type].Deserialize(json, state)); } return(null); }
/// <summary> /// Deserialize the list of <see cref="MemberBinding"/>. /// </summary> /// <param name="list">The list.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The list of member bindings.</returns> private IEnumerable <MemberBinding> DeserializeBindings( IEnumerable <JsonElement> list, SerializationState state) { var result = new List <MemberBinding>(); foreach (var element in list) { var type = (MemberBindingType)element .GetProperty(nameof(MemberBinding.BindingType)) .GetInt32(); switch (type) { case MemberBindingType.Assignment: result.Add(DeserializeAssignment(element, state)); break; case MemberBindingType.MemberBinding: result.Add(DeserializeMember(element, state)); break; case MemberBindingType.ListBinding: result.Add(DeserializeList(element, state)); break; } } return(result); }
/// <summary> /// Deserializes a list. /// </summary> /// <param name="element">The <see cref="JsonElement"/> to parse.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The <see cref="MemberListBinding"/>.</returns> private MemberBinding DeserializeList( JsonElement element, SerializationState state) { var member = GetMemberFromKey( element.GetProperty(nameof(MemberBindingList.MemberKey)) .GetString()); var auth = new List <MemberInfo> { member, }; var initializers = new List <ElementInit>(); foreach (var init in element.GetProperty( nameof(MemberBindingList.Initializers)) .EnumerateArray()) { var addMethod = GetMemberFromKey <MethodInfo>( init.GetProperty(nameof(MemberBindingInitializer.AddMethodKey)) .GetString()); auth.Add(addMethod); initializers.Add(Expression.ElementInit( addMethod, init.GetProperty(nameof(MemberBindingInitializer.Arguments)) .EnumerateArray().Select(json => Serializer.Deserialize(json, state)) .ToArray())); } AuthorizeMembers(auth.ToArray()); return(Expression.ListBind(member, initializers)); }
/// <summary> /// Deserialize a <see cref="MethodExpr"/> to a <see cref="MethodCallExpression"/>. /// </summary> /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="MethodCallExpression"/>.</returns> public override MethodCallExpression Deserialize( JsonElement json, SerializationState state) { Expression obj = null; if (json.TryGetProperty( nameof(MethodExpr.MethodObject), out JsonElement jsonObj)) { obj = Serializer.Deserialize(jsonObj, state); } var key = json.GetProperty(nameof(MethodExpr.MethodInfoKey)) .GetString(); var methodInfo = GetMemberFromKey <MethodInfo>(key); AuthorizeMembers(methodInfo); var list = json.GetProperty(nameof(MethodExpr.Arguments)); var argumentList = list.EnumerateArray().Select(element => Serializer.Deserialize(element, state)).ToList(); if (obj != null) { return(Expression.Call(obj, methodInfo, argumentList)); } return(Expression.Call(methodInfo, argumentList)); }
/// <summary> /// Creates a template of the serializable type with keys decompressed. /// </summary> /// <param name="expression">The <see cref="SerializableExpression"/>.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The <see cref="SerializableExpression"/> instance.</returns> protected TSerializable DecompressTypes( TSerializable expression, SerializationState state) { // single props var parameters = KeyCache .Where(entry => !entry.IsCollection) .Select( cache => (cache.GetKeys(expression)[0], (Action <string>)( s => cache.SetKeys(expression, new[] { s })))) .ToArray(); state.DecompressTypesForKeys(parameters); // lists foreach (var parameter in KeyCache.Where(entry => entry.IsCollection)) { var keys = parameter.GetKeys(expression).Select( k => state.DecompressTypesForKey(k)).ToArray(); parameter.SetKeys(expression, keys); } return(expression); }
/// <summary> /// Deserializes a <see cref="UnaryExpression"/>. /// </summary> /// <param name="unary">The serialized fragment.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The <see cref="UnaryExpression"/>.</returns> public override UnaryExpression Deserialize( Unary unary, SerializationState state) { MethodInfo methodInfo = null; if (!string.IsNullOrWhiteSpace(unary.UnaryMethodKey)) { methodInfo = GetMemberFromKey <MethodInfo>(unary.UnaryMethodKey); } var operand = unary.Operand == null ? null : Serializer.Deserialize(unary.Operand, state); var unaryType = GetMemberFromKey <Type>(unary.UnaryTypeKey); if (methodInfo != null) { return(Expression.MakeUnary( (ExpressionType)unary.Type, operand, unaryType, methodInfo)); } return(Expression.MakeUnary((ExpressionType)unary.Type, operand, unaryType)); }
/// <summary> /// Deserialize the list of <see cref="MemberBinding"/>. /// </summary> /// <param name="list">The list.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The list of member bindings.</returns> private IEnumerable <MemberBinding> DeserializeBindings( IEnumerable <MemberBindingExpr> list, SerializationState state) { var result = new List <MemberBinding>(); foreach (var element in list) { var type = (MemberBindingType)element.BindingType; switch (type) { case MemberBindingType.Assignment: result.Add(DeserializeAssignment((MemberBindingAssignment)element, state)); break; case MemberBindingType.MemberBinding: result.Add(DeserializeMember((MemberBindingMember)element, state)); break; case MemberBindingType.ListBinding: result.Add(DeserializeList((MemberBindingList)element, state)); break; } } return(result); }
/// <summary> /// Deserializes a list. /// </summary> /// <param name="element">The <see cref="MemberBindingList"/> to parse.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The <see cref="MemberListBinding"/>.</returns> private MemberBinding DeserializeList( MemberBindingList element, SerializationState state) { var member = GetMemberFromKey(element.MemberKey); var auth = new List <MemberInfo> { member, }; var initializers = new List <ElementInit>(); foreach (var init in element.Initializers) { var addMethodKey = init.AddMethodKey; typesCompressor.Value.DecompressTypes( state.TypeIndex, (addMethodKey, newKey => addMethodKey = newKey)); var addMethod = GetMemberFromKey <MethodInfo>(addMethodKey); auth.Add(addMethod); initializers.Add(Expression.ElementInit( addMethod, init.Arguments.Select(arg => Serializer.Deserialize(arg, state)) .ToArray())); } AuthorizeMembers(auth.ToArray()); return(Expression.ListBind(member, initializers)); }
/// <summary> /// Compress the types on the serializable class. /// </summary> /// <param name="serializable">The serializable entity.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> public void CompressTypes( SerializableExpression serializable, SerializationState state) { if (KeyCache.Count < 1) { return; } var expression = (TSerializable)serializable; // single props var parameters = KeyCache .Where(entry => !entry.IsCollection) .Select( cache => (cache.GetKeys(expression)[0], (Action <string>)( s => cache.SetKeys(expression, new[] { s })))) .ToArray(); state.CompressTypesForKeys(parameters); // lists foreach (var parameter in KeyCache.Where(entry => entry.IsCollection)) { var keys = parameter.GetKeys(expression).Select( k => state.CompressTypesforKey(k)).ToArray(); parameter.SetKeys(expression, keys); } }
/// <summary> /// Serializes the expression. /// </summary> /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param> /// <returns>The serializable <see cref="Constant"/>.</returns> public override Constant Serialize(ConstantExpression expression, SerializationState state) { if (expression == null) { return(null); } if (expression.Type.IsAnonymousType()) { expression = Expression.Constant( ConvertAnonymousTypeToAnonType(expression.Value), typeof(AnonType)); } var result = new Constant(expression); if (expression.Value is Expression expr) { result.Value = Serializer.Serialize(expr, state); result.ValueTypeKey = GetKeyForMember(result.Value.GetType()); } if (result.ValueTypeKey == result.ConstantTypeKey) { result.ValueTypeKey = null; } return(result); }
/// <summary> /// Deserialize a <see cref="MemberExpr"/> to a <see cref="MemberExpression"/>. /// </summary> /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="MemberExpression"/>.</returns> public override MemberExpression Deserialize( JsonElement json, SerializationState state) { Expression expr = null; if (json.TryGetProperty( nameof(MemberExpr.Expression), out JsonElement jsonObj)) { expr = Serializer.Deserialize(jsonObj, state); } var memberInfo = GetMemberFromKey(json .GetProperty(nameof(MemberExpr.MemberTypeKey)).GetString()); if (json.TryGetProperty(nameof(MemberExpr.Indexer), out JsonElement indexer)) { if (!string.IsNullOrWhiteSpace(indexer.GetString())) { return(null); } } AuthorizeMembers(new[] { memberInfo }); return(Expression.MakeMemberAccess(expr, memberInfo)); }
/// <summary> /// Deserializes a <see cref="UnaryExpression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="UnaryExpression"/>.</returns> public override UnaryExpression Deserialize( JsonElement json, SerializationState state) { var methodKey = json.GetNullableProperty(nameof(Unary.UnaryMethodKey)); MethodInfo methodInfo = null; if (methodKey.ValueKind != JsonValueKind.Null) { var key = methodKey.GetString(); if (!string.IsNullOrWhiteSpace(key)) { methodInfo = GetMemberFromKey <MethodInfo>(key); } } var expressionType = (ExpressionType)json.GetProperty(nameof(SerializableExpression.Type)).GetInt32(); var operandElement = json.GetNullableProperty(nameof(UnaryExpression.Operand)); var operand = Serializer.Deserialize(operandElement, state); var unaryType = GetMemberFromKey <Type>(json.GetProperty(nameof(Unary.UnaryTypeKey)).GetString()); if (methodInfo != null) { return(Expression.MakeUnary( expressionType, operand, unaryType, methodInfo)); } return(Expression.MakeUnary(expressionType, operand, unaryType)); }
/// <summary> /// Deserializes a <see cref="LambdaExpression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="LambdaExpression"/>.</returns> public override LambdaExpression Deserialize( JsonElement json, SerializationState state) { var materializedType = GetMemberFromKey <Type>( json.GetProperty(nameof(Lambda.LambdaTypeKey)) .GetString()); var materializedReturnType = GetMemberFromKey <Type>(json.GetProperty(nameof(Lambda.ReturnTypeKey)) .GetString()); var name = json.GetNullableProperty(nameof(Lambda.Name)).GetString(); var list = json.GetNullableProperty(nameof(Lambda.Parameters)); var parameterList = list.ValueKind == JsonValueKind.Array ? list.EnumerateArray().Select(element => Serializer.Deserialize(element, state) as ParameterExpression).ToList() : new List <ParameterExpression>(); var jsonBody = json.GetProperty(nameof(Lambda.Body)); Expression body = Serializer.Deserialize(jsonBody, state); return(Expression.Lambda( materializedType, body, name, parameterList)); }
/// <summary> /// Deserializes a <see cref="NewArrayExpression"/>. /// </summary> /// <param name="newArray">The serialized fragment.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The <see cref="NewArrayExpression"/>.</returns> public override NewArrayExpression Deserialize( NewArray newArray, SerializationState state) { var materializedType = GetMemberFromKey <Type>(newArray.ArrayTypeKey); var expressionList = newArray.Expressions.Select(element => Serializer.Deserialize( element, state)).ToList(); return(Expression.NewArrayInit(materializedType, expressionList)); }
/// <summary> /// Deserialize a serializable class to an actionable <see cref="Expression"/>. /// </summary> /// <param name="param">The serialized fragment.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The deserialized <see cref="Expression"/>.</returns> public override ParameterExpression Deserialize( Parameter param, SerializationState state) { Type type = GetMemberFromKey <Type>(param.ParameterTypeKey); var parameter = string.IsNullOrWhiteSpace(param.Name) ? Expression.Parameter(type) : Expression.Parameter(type, param.Name); return(state.GetOrCacheParameter(parameter)); }
/// <summary> /// Deserializes a <see cref="InvocationExpression"/>. /// </summary> /// <param name="expr">The serialized fragment.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The <see cref="InvocationExpression"/>.</returns> public override InvocationExpression Deserialize( Invocation expr, SerializationState state) { var expression = Serializer.Deserialize(expr.Expression, state); var argumentList = expr.Arguments.Select(element => Serializer.Deserialize(element, state)).ToList(); return(Expression.Invoke(expression, argumentList)); }
/// <summary> /// Deserialize a serializable class to an actionable <see cref="Expression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The deserialized <see cref="Expression"/>.</returns> public override ParameterExpression Deserialize( JsonElement json, SerializationState state) { var type = GetMemberFromKey <Type>(json.GetProperty(nameof(Parameter.ParameterTypeKey)).GetString()); var name = json.GetNullableProperty(nameof(Parameter.Name)).GetString(); var parameter = string.IsNullOrWhiteSpace(name) ? Expression.Parameter(type) : Expression.Parameter(type, name); return(state.GetOrCacheParameter(parameter)); }
/// <summary> /// Deserializes a <see cref="NewArrayExpression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="NewArrayExpression"/>.</returns> public override NewArrayExpression Deserialize( JsonElement json, SerializationState state) { var materializedType = GetMemberFromKey <Type>(json.GetProperty(nameof(NewArray.ArrayTypeKey)).GetString()); var list = json.GetProperty(nameof(NewArray.Expressions)); var expressionList = list.EnumerateArray().Select(element => Serializer.Deserialize( element, state)).ToList(); return(Expression.NewArrayInit(materializedType, expressionList)); }
/// <summary> /// Deserializes a <see cref="InvocationExpression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="InvocationExpression"/>.</returns> public override InvocationExpression Deserialize( JsonElement json, SerializationState state) { var expr = json.GetProperty(nameof(Invocation.Expression)); var expression = Serializer.Deserialize(expr, state); var list = json.GetNullableProperty(nameof(Invocation.Arguments)); var argumentList = list.EnumerateArray().Select(element => Serializer.Deserialize(element, state)).ToList(); return(Expression.Invoke(expression, argumentList)); }
/// <summary> /// Deserialize a serializable class to an actionable <see cref="Expression"/>. /// </summary> /// <param name="json">The serialized fragment.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The deserialized <see cref="Expression"/>.</returns> public override ConstantExpression Deserialize( JsonElement json, SerializationState state) { var value = json.GetNullableProperty(nameof(Constant.Value)).GetRawText(); var type = GetMemberFromKey <Type>(json.GetProperty(nameof(Constant.ConstantTypeKey)).GetString()); var valueNode = json.GetNullableProperty(nameof(Constant.ValueTypeKey)); var valueType = valueNode.ValueKind != JsonValueKind.Null ? GetMemberFromKey <Type>(valueNode.GetString()) : type; if (typeof(SerializableExpression).IsAssignableFrom(valueType)) { var innerValue = Serializer.Deserialize( json.GetProperty(nameof(Constant.Value)), state); return(Expression.Constant(innerValue, innerValue.GetType())); } if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(EnumerableQuery <>)) { if (state.QueryRoot is ConstantExpression ce) { return(ce); } return(state.QueryRoot != null? Expression.Constant(state.QueryRoot) : Expression.Constant(null, valueType)); } if (typeof(MemberInfo).IsAssignableFrom(valueType)) { var memberKey = JsonSerializer.Deserialize <string>(value, state.Options); return(Expression.Constant(GetMemberFromKey(memberKey))); } var constantVal = JsonSerializer.Deserialize( value, valueType, state.Options); if (constantVal is AnonType anonType) { constantVal = ConvertAnonTypeToAnonymousType( anonType, state.Options); } return(type == valueType && constantVal != null?Expression.Constant(constantVal) : Expression.Constant(constantVal, type)); }
/// <summary> /// Serializes the expression. /// </summary> /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param> /// <returns>The serializable <see cref="Constant"/>.</returns> public override Parameter Serialize( ParameterExpression expression, SerializationState state) { if (expression == null) { return(null); } var result = new Parameter(expression); return(result); }
/// <summary> /// Deserializes an assignment. /// </summary> /// <param name="element">The <see cref="JsonElement"/> to parse.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The <see cref="MemberAssignment"/>.</returns> private MemberBinding DeserializeAssignment(JsonElement element, SerializationState state) { var member = GetMemberFromKey( element.GetProperty(nameof(MemberBindingAssignment.MemberInfoKey)) .GetString()); AuthorizeMembers(member); var expression = Serializer.Deserialize( element.GetProperty(nameof(MemberBindingAssignment.Expression)), state); return(Expression.Bind(member, expression)); }
/// <summary> /// Deserialize a <see cref="MemberInit"/> to a <see cref="MemberInitExpression"/>. /// </summary> /// <param name="memberInit">The <see cref="MemberInit"/> to deserialize.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The <see cref="MemberInitExpression"/>.</returns> public override MemberInitExpression Deserialize( MemberInit memberInit, SerializationState state) { NewExpression expr = null; if (memberInit.NewExpression != null) { expr = Serializer.Deserialize(memberInit.NewExpression, state) as NewExpression; } var memberBindings = DeserializeBindings(memberInit.Bindings, state); return(Expression.MemberInit(expr, memberBindings.ToArray())); }
/// <summary> /// Serialize a <see cref="UnaryExpression"/> to a <see cref="Unary"/>. /// </summary> /// <param name="expression">The <see cref="UnaryExpression"/>.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The <see cref="Unary"/>.</returns> public override Unary Serialize( UnaryExpression expression, SerializationState state) { if (expression == null) { return(null); } var unary = new Unary(expression) { Operand = Serializer.Serialize(expression.Operand, state), }; return(unary); }
/// <summary> /// Deserializes a member binding. /// </summary> /// <param name="element">The <see cref="JsonElement"/> to parse.</param> /// <param name="state">The <seealso cref="SerializationState"/>.</param> /// <returns>The <see cref="MemberMemberBinding"/>.</returns> private MemberBinding DeserializeMember( JsonElement element, SerializationState state) { var member = GetMemberFromKey( element.GetProperty(nameof(MemberBindingMember.MemberKey)) .GetString()); AuthorizeMembers(member); var bindings = DeserializeBindings( element.GetProperty(nameof(MemberBindingMember.Bindings)) .EnumerateArray(), state).ToArray(); return(Expression.MemberBind(member, bindings)); }
/// <summary> /// Serialize a <see cref="MemberExpression"/>. /// </summary> /// <param name="expression">The <see cref="MemberExpression"/> to serialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param> /// <returns>The serializable <see cref="MemberExpr"/>.</returns> public override MemberExpr Serialize( MemberExpression expression, SerializationState state) { if (expression == null) { return(null); } var member = new MemberExpr(expression) { Expression = Serializer.Serialize(expression.Expression, state), }; return(member); }
/// <summary> /// Deserialize a <see cref="CtorExpr"/> to a <see cref="NewExpression"/>. /// </summary> /// <param name="json">The <see cref="JsonElement"/> to deserialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the deserialization.</param> /// <returns>The <see cref="NewExpression"/>.</returns> public override NewExpression Deserialize( JsonElement json, SerializationState state) { var ctorDescriptor = json.GetProperty(nameof(CtorExpr.CtorInfo)).GetString(); var ctor = GetMemberFromKey <ConstructorInfo>(ctorDescriptor); var members = new List <MemberInfo>(); if (json.TryGetProperty( nameof(CtorExpr.MemberKeys), out JsonElement memberList)) { members = memberList.EnumerateArray() .Select(memberJson => memberJson.GetString()) .Select(memberKey => GetMemberFromKey(memberKey)) .ToList(); } var args = new List <Expression>(); if (json.TryGetProperty( nameof(CtorExpr.Arguments), out JsonElement arguments)) { foreach (var argElem in arguments.EnumerateArray()) { var arg = Serializer.Deserialize(argElem, state); args.Add(arg); } } AuthorizeMembers(ctor); if (args.Count == 0) { return(Expression.New(ctor)); } if (members.Count == 0) { return(Expression.New(ctor, args)); } return(Expression.New(ctor, args, members)); }
/// <summary> /// Serializes the expression. /// </summary> /// <param name="expression">The <see cref="ConstantExpression"/> to serialize.</param> /// <param name="state">State, such as <see cref="JsonSerializerOptions"/>, for the serialization.</param> /// <returns>The serializable <see cref="Constant"/>.</returns> public override Constant Serialize(ConstantExpression expression, SerializationState state) { if (expression == null) { return(null); } var result = new Constant(expression); if (expression.Value is Expression expr) { result.Value = Serializer.Serialize(expr, state); result.ValueTypeKey = GetKeyForMember(result.Value.GetType()); } return(result); }
/// <summary> /// Deserializes an assignment. /// </summary> /// <param name="element">The <see cref="MemberBindingAssignment"/> to parse.</param> /// <param name="state">The <see cref="SerializationState"/>.</param> /// <returns>The <see cref="MemberAssignment"/>.</returns> private MemberBinding DeserializeAssignment(MemberBindingAssignment element, SerializationState state) { var key = element.MemberInfoKey; typesCompressor.Value.DecompressTypes( state.TypeIndex, (key, newKey => key = newKey)); var member = GetMemberFromKey(key); AuthorizeMembers(member); var expression = Serializer.Deserialize( element.Expression, state); return(Expression.Bind(member, expression)); }
/// <summary> /// Serialize a <see cref="MemberInitExpression"/>. /// </summary> /// <param name="expression">The <see cref="MemberInitExpression"/> to serialize.</param> /// <param name="state">State for the serialization or deserialization.</param> /// <returns>The serializable <see cref="MemberInit"/>.</returns> public override MemberInit Serialize( MemberInitExpression expression, SerializationState state) { if (expression == null) { return(null); } var memberInit = new MemberInit(expression) { NewExpression = (CtorExpr)Serializer.Serialize(expression.NewExpression, state), }; memberInit.Bindings.AddRange(SerializeBindings(expression.Bindings, state)); return(memberInit); }