private Expression MakeEnumLambda(Type type)
        {
            var p = Expression.Parameter(typeof(string), "s");

            var c = ReflectionCacheManager.GetEnumCache(type).Cache;

            var fields = c.Fields;

            List <SwitchCase> cases = new List <SwitchCase>();

            foreach (var f in fields)
            {
                if (f.Field.FieldType.IsEnum)
                {
                    var val = f.Field.GetValue(null);

                    var caseConditions = f.Attributes.Where(v => v.Key == typeof(XmlEnumAttribute) || v.Key == typeof(XmlEnumAlternateName))
                                         .SelectMany(a => a.Value).Cast <XmlEnumAttribute>().Select(a => Expression.Constant(a.Name)).ToArray();

                    if (caseConditions.Length > 0)
                    {
                        cases.Add(Expression.SwitchCase(Expression.Constant(val), caseConditions));
                    }
                }
            }

            var failEnum      = XmlExpressionConstants.FailEnum(p, type);
            var throwFailEnum = Expression.Throw(failEnum, type);

            Expression switchBody;

            if (cases.Count > 0)
            {
                switchBody = Expression.Switch(p, throwFailEnum, cases.ToArray());
            }
            else
            {
                switchBody = throwFailEnum;
            }

            var lambda = Expression.Lambda(
                Expression.Block(switchBody),
                $"Read{type.Name}",
                new[] { p, XmlExpressionConstants.Serializer });

            return(XmlSerializerGenerator.LambdaOrDelegate(lambda));
        }
示例#2
0
        private LambdaExpression MakeSwitchLambda(ParameterExpression property, ParameterExpression rawValue)
        {
            var c = ReflectionCacheManager.GetEnumCache(propertyType).Cache;

            var fields = c.Fields;

            List <SwitchCase> cases = new List <SwitchCase>();

            foreach (var f in fields)
            {
                if (f.Field.FieldType.IsEnum)
                {
                    var val = f.Field.GetValue(null);

                    Expression body = GetCaseBody((Enum)val, rawValue);

                    if (body != null)
                    {
                        if (body.NodeType != ExpressionType.Block)
                        {
                            body = Expression.Convert(body, typeof(object));
                        }

                        cases.Add(Expression.SwitchCase(body, Expression.Constant(val)));
                    }
                }
            }

            var @default = Expression.Constant(null);

            var assignName = XmlExpressionConstants.Serializer_Name(XmlAttributeType.Element).Assign(property.Call("ToString").Call("ToLower"));

            var @switch = Expression.Switch(property, @default, cases.ToArray());

            return(Expression.Lambda(
                       Expression.Block(
                           assignName,
                           @switch
                           ),
                       "ReadObjectPropertyInner",
                       new[] { XmlExpressionConstants.Serializer, property, rawValue }));
        }